反射是Java中的一个重要的特性,使用反射可以在运行时动态生成对象、获取对象属性以及调用对象方法。与编译期的静态行为相对,所有的静态型操作都在编译期完成,而反射的所有行为基本都是在运行时进行的,这是一个很重要的特性。它让Java有了动态特性,可以让程序更加灵活强大
反射的背景和应用
反射大量运用在框架代码和工具代码中,因为这类工程项目往往对于灵活性的要求较高,在实际的业务代码中我们其实使用反射并不多。因此这也就引出了,大部分时候做业务的我们为什么要学习反射原理的原因:为了更加深刻地理解我们所用的工具和框架,了解了反射原理,我们能够在使用框架时优化出更好的性能
原理
java程序在编译完成后,会把所有class文件中所包含的类的基本元信息装载到JVM内存中,以Class类的形式保存,每一个Class类对象代表一个具体类的基本元信息。我们的反射就是在Class类的基础上进行的,Class类对象存储着类的所有相关信息,就像镜子,故称“反射”。
反射总体流程:
准备阶段:编译期装载所有的类,将每个类的元信息保存至Class类对象中,每一个类对应一个Class对象
获取Class对象:调用x.class/x.getClass()/Class.forName() 获取x的Class对象clz(这些方法的底层都是native方法,是在JVM底层编写好的,涉及到了JVM底层,就先不进行探究了)
进行实际反射操作:通过clz对象获取Field/Method/Constructor对象进行进一步操作
class类 :代表一个类,是Java反射机制的起源和入口
用于获取与类相关的各种信息, 提供了获取类信息的相关方法
Class类继承自Object类
Class类是所有类的共同的图纸
每个类有自己的对象,同时每个类也看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应的信息:类的名字、属性、方法、构造方法、父类和接口。
反射提供的功能
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法
反射的使用
通过Class.forName("全类名")
Class actionClass=Class.forName(“MyClass”);
Object action=actionClass.newInstance();
Method method = actionClass.getMethod(“myMethod”,null);
method.invoke(action,null)
反射效率提升
缓存重复用到的对象
void createInstance(String className){
cachedClass = cache.get(className);
if (cachedClass == null){
cachedClass = Class.forName(className);
cache.set(className, cachedClass); }
return cachedClass.newInstance();
setAccessible(true)
accessible 标志被设置为true,那么反射对象在使用的时候,不会去检查Java语言权限控制(private之类的)
网友评论