反射指的是在运行状态,能动态地获取编译期未确定的类,并且对于任意的一个类或对象,都能获取及调用其所有的属性和方法。如在idea中我们创建了一个object对象,输入object. 之后idea会自动提示object的所有属性和方法。
其实本质就是Java程序到了运行的时候再去加载某一个类(.class文件),然后获取属性方法等各种信息
Java在编译时会生成.class文件,运行时jvm会将.class文件加载进内存生成对应的class对象。
注:但因为反射影响性能,不如直接编写的Java代码效率高,现在被运行时注解APT替代了。不过许多框架的底层都是使用反射完成的,因此反射的了解还是有必要的。
String s = "ab";
System.out.println(s.getClass());
System.out.println(Class.forName("java.lang.String"));
System.out.println(String.class);
获取完class对象之后,我们便可以根据这个class对象获取该类的所有属性、方法和构造器。
反射更为强大的一个地方在于能够获取用private修饰的类的属性和方法。
1)首先我们先定义一个Dog类
public class Dog {
public String name;
private int age;
public Dog(){
}
private Dog(String name,int age){
this.name = name;
this.age = age;
}
}
在此我们定义了一个public和private的属性,一个public和private的构造器,来探究反射能否获取private修饰的属性和方法。get和set方法都设置为public,在此省略。
2)获取Dog的Class对象
Class dogClass = Class.forName("reflection.Dog");
System.out.println(dogClass);
上面提到的三种获取类对象的方法都可以,在这里我们使用Class.forName()获取
3)获取所有的构造器方法
constructors.setAccessible(true);
);加了s的为获取所有,没加s的获取匹配参数的。Constructor[] constructors = dogClass.getDeclaredConstructors();
System.out.println(Arrays.toString(constructors));
因为可能会存在多个构造器,我们使用了数组来保存构造器对象。我们可以发现private修饰的构造器也成功获取了。
4)获取的构造器对象创建一个类的对象实例
获取一个构造器对象,通过newInstance方法创建Dog的实例
Constructor constructor = dogClass.getDeclaredConstructor(String.class, int.class);
constructor.setAccessible(true);
Dog dog = (Dog) constructor.newInstance("mingming", 12);
System.out.println(dog);
5)获取属性和方法
获取属性和方法的过程大致与获取构造器的相同,这里就不再累赘了
较为重要的:method中使用invoke执行
Method method = dogClass.getDeclaredMethod("toString");
System.out.println(method.invoke(dog));
说了这么多,我们大概也都知道了反射实际上就是获取class对象,然后通过这个class对象获取constructor、field、method对象。接着我们便可以通过constructor实例化对象、通过method执行方法。
但是,我们明明可以直接new一个对象,然后Object.method执行方法。为什么还要这么麻烦呢?
举个例子:
我们有Dog,Cat,Bird类,继承自Animal类,都可执行eat方法。假设我们最开始是要dog.eat,编译执行完之后需求改了,需求改了,变成了cat.eat,此时我们需要修改源代码,并且重新编译上线。这样显然非常地不灵活。而我们使用反射后,便可将信息保存在xml文件中,修改时无须重新编译。
原来:new Animal()
;
反射:Class.forName("Animal").newInstance()
//无参构造方法
怎么样,是不是很眼熟?
参考博文:
https://blog.csdn.net/huangliniqng/article/details/88554510
https://blog.csdn.net/JAck_chen0309/article/details/105427350
https://blog.csdn.net/Appleyk/article/details/77879073
感谢整理和分享!