Java的反射机制允许我们动态的调用某个对象的方法/构造函数、获取某个对象的属性等,而无需在编码时确定调用的对象。
Method
JDK中
Method.invoke()
实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor
来处理的。
首先要了解Method对象的基本构成,每个Java方法有且只有一个Method对象作为root
,它相当于根对象,对用户不可见。当我们创建Method对象时,我们代码中获得的Method对象都相当于它的副本(或引用)。root对象持有一个MethodAccessor对象,所以所有获取到的Method对象都共享这一个MethodAccessor对象,因此必须保证它在内存中的可见性。
JDK 1.8中Method.invoke()
源码
MethodAccessor
MethodAccessor
的实例是由sun.reflect.ReflectionFactory
创建的。
实际的MethodAccessor实现有两个版本,一个是Java实现的,另一个是native code实现的。
Java实现的版本在初始化时需要较多时间,但长久来说性能较好;
native版本正好相反,启动时相对较快,但运行时间长了之后速度就比不过Java版了。
为了权衡两个版本的性能,Sun的JDK使用了“inflation”的技巧:让Java方法在被反射调用时,开头若干次使用native版,等反射调用次数超过阈值时则生成一个专用的MethodAccessor实现类,生成其中的invoke()方法的字节码,以后对该Java方法的反射调用就会使用Java版。
invoke方法调用过程