Java方法反射实现原理详解

  

<>强博主说:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。在本文中,占小狼分析了Java反射机制的实现原理(源码),感兴趣的同学可以通过阅读本文花上几分钟了解了解。

  

<强>正文

  

癑ava方法反射实现原理详解"

  

方法反射实例

        公开课ReflectCase {      公共静态void main (String [] args){抛出异常   代理目标=new代理();   方法方法=Proxy.class.getDeclaredMethod(“运行”);   method.invoke(目标);   }      静态类代理{   公共空间run () {   System.out.println(“运行”);   }   }   }      之前      

通过Java的反射机制,可以在运行期间调用对象的任何方法,如果大量使用这种方式进行调用,会有性能或内存隐患么?为了彻底了解方法的反射机制,只能从底层代码入手啦!

  

<强>方法获取

  

调用类类的getDeclaredMethod可以获取指定方法名和参数的方法对象方法。

  

<强> getDeclaredMethod

  

癑ava方法反射实现原理详解"

  

其中privateGetDeclaredMethods方法从缓存或JVM中获取该班级中申明的方法列表,searchMethods方法将从返回的方法列表里找到一个匹配名称和参数的方法对象。

  

<强> searchMethods

  

癑ava方法反射实现原理详解"

  

如果找到一个匹配的方法,则重新复制一份返回,即<代码> Method.copy() 方法。

  

癑ava方法反射实现原理详解"

  

所次每次调用getDeclaredMethod方法返回的方法对象其实都是一个新的对象,且新对象的根属性都指向原来的方法对象,如果需要频繁调用,最好把方法对象缓存起来。

  

<强> privateGetDeclaredMethods

  

从缓存或JVM中获取该班级中申明的方法列表,实现如下:

  

癑ava方法反射实现原理详解"

  

其中reflectionData()方法实现如下:

  

癑ava方法反射实现原理详解"

  

这里有个比较重要的数据结构ReflectionData,用来缓存从JVM中读取类的如下属性数据:

  

癑ava方法反射实现原理详解"

  

从reflectionData()方法实现可以看出:reflectionData对象是SoftReference类型的,说明在内存紧张时可能会被回收,不过也可以通过- xx: SoftRefLRUPolicyMSPerMB参数控制回收的时机,只要发生GC就会将其回收,如果reflectionData被回收之后,又执行了反射方法,那只能通过newReflectionData方法重新创建一个这样的对象了,newReflectionData方法实现如下:

  

癑ava方法反射实现原理详解"

  

通过unsafe.compareAndSwapObject方法重新设置reflectionData字段;在privateGetDeclaredMethods方法中,如果通过reflectionData()获得的reflectionData对象不为空,则尝试从reflectionData对象中获取declaredMethods属性,如果是第一次,或则被GC回收之后,重新初始化后的类属性为空,则需要重新到JVM中获取一次,并赋值给reflectionData,下次调用就可以使用缓存数据了。

  

<强>方法调用

  

获取到指定的方法对象方法之后,就可以调用它的调用方法了,调用实现如下:

  

癑ava方法反射实现原理详解"

  

应该注意到:这里的MethodAccessor对象是调用方法实现的关键,一开始MethodAccessor为空,需要调用acquireMethodAccessor生成一个新的MethodAccessor对象,MethodAccessor本身就是一个接口,实现如下:

  

癑ava方法反射实现原理详解"

  

Java方法反射实现原理详解