Java反射是指在运行时能够获取一个类的全部信息。
比如说有一个类MyService
public class MyService {
private String nameA;
public String nameB;
public MyService() {
this.nameA = null;
this.nameB = null;
}
public MyService(String nameA, String nameB) {
this.nameA = nameA;
this.nameB = nameB;
}
private void funcA() {
}
public void funcB() {
}
protected void funcC() {
}
public String funcD(int param1, String param2, Boolean param3) {
return "----funcD----";
}
}
假如说我新建了一个实例,希望能够获取这个private的nameA的属性的值。那就可以用反射实现。(注意:因为nameA是private修饰符,所以需要使用getDeclaredField
来获得,如果使用getField
的话会报NoSuchFieldException
错误)
public class Test {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
MyService myService = new MyService("aaa", "bbb");
Field field = myService.getClass().getDeclaredField("nameA");
field.setAccessible(true);
System.out.println(field.get(myService));
}
}
还可以通过反射来创建类的实例,假如说我知道一个类的全路径名字,那么就可以使用以下方法来创建实例:
Class<?> clazz = Class.forName("site.nemo.learn.reflect.MyService");
Object obj = clazz.newInstance();
上面clazz.newInstance()
其实是调用了无参构造器生成了一个实例,但其实我们还定义了一个有参构造器。
我们可以使用反射来获取这个有参构造器
// 获取到了有参构造器
Constructor<?> constructor =clazz.getConstructor(String.class, String.class);
// 调用了有参构造器创建实例
Object obj2 = constructor.newInstance("qqq", "www");
// 类型转换
MyService myService2 = (MyService) obj2;
// 打印
System.out.println(myService2.nameB);
还可以通过反射API获取类的其他信息,具体在java.lang.reflect包里面可以看到。
Java里面将类这个东西的各个部分都抽象出来了
Java里面使用Class
这个类来描述类这个东西。类有:类名、全路径名、构造函数、成员变量、方法……
构造函数就用Constructor
这个类来描述,构造器有:名字、参数列表……
成员变量就用Field
这个类来描述,成员变量有: 变量名、修饰符、类型……
类的方法就用Method
这个类来描述,方法有 :方法名、修饰符、返回值类型、参数列表……