Java反射机制

引言

  • 最近的项目中,需要根据客户端传入的id来动态的实例化对象,所以学习了一下java的反射机制;

反射的定义

  • 反射是指程序可以访问、检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义;
  • import是在程序编译时,静态引入相应类,反射是程序运行时,根据某一字符串,访问、创建这个字符串描述的类或是它的方法;

反射的作用

  • 在运行时判断任意一个对象所属的类 ;
  • 在运行时构造任意一个类的对象 ;
  • 在运行时判断任意一个类所具有的成员变量和方法 ;
  • 在运行时调用任意一个对象的方法;

反射所需的API

都位于java.lang.reflect包中:

  • Class类:代表一个类,位于java.lang包下;
  • Field类:代表类的成员变量(成员变量也称为类的属性);
  • Method类:代表类的方法;
  • Constructor类:代表类的构造方法;
  • Array类:提供了动态创建数组,以及访问数组的元素的静态方法;

反射实例

  • 获取Class对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package test12;

public class Employee {

public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Class.forName("test12.Employee");
Class c2 = Employee.class;
Employee e = new Employee();
Class c3 = e.getClass();

System.out.println(c1); //class test12.Employee
System.out.println(c2); //class test12.Employee
System.out.println(c3); //class test12.Employee
}

}
  • 获取所有成员变量:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package test12;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Employee {

public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class<?> c = Class.forName("test12.test");

//获取所有成员变量
Field[] f = c.getFields();
for(int i =0; i<f.length; i++){
System.out.println(f[i]); //public int test12.test.c
}
}
}
  • 获取特定的成员变量:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package test12;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Employee {

public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
Class<?> c = Class.forName("test12.test");

//获取特定成员变量
Field f = c.getField("c");
System.out.println(f); //public int test12.test.c
Field f1 = c.getField("d"); //java.lang.NoSuchFieldException
System.out.println(f1);
}
}
  • 获取所有方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package test12;

import java.lang.reflect.Method;

public class Employee {

public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("java.lang.String");

Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method); //输出所有方法
}
}

}
  • 获取特定的方法并调用之
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package test12;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Employee {

public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c = Class.forName("test12.test");

//获取方法
Object t = c.newInstance();
System.out.println(t instanceof test); //true

//调用方法
Method stringMethod = c.getDeclaredMethod("plus", new Class[]{int.class, int.class});
Object result = stringMethod.invoke(t, new Object[]{1,2});
System.out.println(result); //3
System.out.println(result instanceof Integer); //true
}
}
1
2
3
4
5
6
7
8
//test类
package test12;

public class test {
public int plus(int a, int b){
return a+b;
}
}
  • 动态生成对象(构造器不含参数)
1
2
Class<?> classType = String.class;
Object obj = classType.newInstance();
  • 动态生成对象(构造器含参数):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package test12;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Employee {

public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c = Class.forName("test12.test");

//获取构造器并实例化类
Constructor cons = c.getConstructor(new Class[] {int.class, int.class});
Object obj = cons.newInstance(new Object[] {10,20});

//调用方法
Method stringMethod = c.getDeclaredMethod("plus");
Object result = stringMethod.invoke(obj);
System.out.println(result); //30
System.out.println(result instanceof Integer); //true
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//test类
package test12;

public class test {
private int a;
private int b;

public test(int a, int b){
this.a = a;
this.b = b;
}

public int plus(){
return a+b;
}
}
您的支持是对我最大的鼓励!