在Effective Java中有一条规则是关于反射:接口优先于反射机制
在探讨这个规则的使用和理解之前我想重新整理下关于我对反射的认知:
反射,就是指在运行时去获取已经加载在jvm中的class文件中的信息然后去获取该类的实例、属性、方法的,这种运行时动态获取该类信息和调用对应方法的功能就称为java的反射机制。
原理就是: 获取已经加载好的class文件里面的信息,也就是字节码文件对象,解析里面的信息后获取到对应的Class对象,该对象包含把成员属性、方法等等信息组装好,我们可以去获取,调用和set值。使用的三种方式:
- 对象实例调用getClass()方法.
- 类名获取.Class。
- Class.forName("类名"),返回。
不想贴代码了。
一般来说,在我们实际的应用程序中,我基本上很少用这个东西,我在手写一个Spring demo框架的时候,在实现IOC功能是,会去获取全路径下的类,通过反射去获取该对象实例,存入IOC容器,所以一般来说,
反射功能只是在设计时被用到。通常,普通应用程序在运行时不应该以反射的方式访问对象。
反射的效率是很低的,因为需要解析字节码文件内容,然后组装后返回。
通过反射返回的Class实例会包含所代表类的构造器Constructor(构造器),Method(方法)和Field(域)。这些对象提供了“通过程序来访问类的成员名称,域类型,方法签名等信息”的能力。
而且,Constructor,Method和Field实例使你能够通过反射机制操作它们的底层对等体(就是这个类的构造器,方法,域),通过调用Constructor,Method和Field实例上的方法,你可以构造底层类的实例,调用底层类的方法,并访问底层类中的域。反射机制允许一个类使用另一个类,即使当前者被编译的时候后者还根本不存在。
使用反射机制的缺点:
1,丧失了编译时类型检查的好处,包括异常检查;
2,执行反射访问所需要的代码非常笨拙和冗长。
2,性能损失。反射方法调用比普通方法调用慢了很多。
对于有些程序,它们必须用到在编译时无法获取的类,但是在编译时存在适当的接口或者超类,通过它们可以引用到这个类。如果是这种情况,就可以以反射方式创建实例,然后通过它们的接口或者超类,以正常的方式访问这些实例。
网友评论