目录
2.4 枚举和反射(阿里面试:为什么枚举实现单例模式是安全的?)
1、反射
1.1 反射的定义
Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任 意一个对象,都能够调用它的任意方法和属性,也能够修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
简单来说,反射就是在运行的状态下,能够看清类的基本信息。
我们可以这样理解:在安检时,我们把行李箱放在安检的机器上,这时,不管行李箱里面有什么东西,哪怕是私密的东西,也可以被看的一清二楚。
1.2 反射机制的原理
一个.java文件经过编译会生成.class字节码文件,在运行时,这个字节码文件又会被JVM解析成一个Class类的对象,程序在运行时,每个java文件最终就会变成Class类对象的一个实例,我们就可以通过这个Class类来获取或修改类的基本信息。
也就是说,在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象(见下文),然后通过Class对象的核心方法,达到反射的目的,
1.3 反射相关类
要想实现反射,我们必须了解以下类:
- Class类:代表类的实体,在运行的Java应用程序中表示类和接口
- Field类:代表类的成员变量/类的属性
- Method类:代表类的方法
- Constructor类:代表类的构造方法
1.4 Class类
1.4.1 相关方法
1.4.1.1 常用获得类相关的方法
1.4.1.2 常用获得类中属性相关的方法
1.4.1.3 获得类中构造器相关的方法
1.4.1.4 获得类中方法相关的方法
1.4.2 获取Class对象
-
第一种,使用 Class.forName("类的全路径名"); (静态方法)(常用) 例:Class<?> c1 = Class.forName("reflectdemo.Student");
-
使用 .class 方法。 例:Class c2 = Student.class;
-
使用类对象的 getClass() 方法。 例:Student student = new Student();Class<?> c3 = student.getClass();
1.5 总结
反射优点:
- 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。
- 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力。
- 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。
反射缺点:
- 调用大量方法,导致程序效率降低 。
- 会带来维护问题。
- 反射代码比相应的直接代码更复杂 。
1.6 代码实例
public static void reflectPrivateField() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
Field field = c1.getDeclaredField("name");
field.setAccessible(true);//修改private修饰的成员,需要添加这条语句
//获取Student对象
Student student = (Student)c1.newInstance();
field.set(student,"poll"