One, reflection source code interpretation

1. Method

GetDeclaredMethod getDeclaredMethod getDeclaredMethod getDeclaredMethodCopy the code

Including: 1) privateGetDeclaredMethods method from the cache or the JVM to get the statement of the method in the Class list 2) searchMethods method will return from the list to find a match object name and parameter methodCopy the code

If a matching Method is found, a new copy is returned, the method.copy () MethodCopy the code

The Method object returned by getDeclaredMethod is actually a new object, and the root attribute of the new object points to the original Method object. If you need to call it frequently, it is best to cache the Method object.Copy the code

2, privateGetDeclaredMethods

Get the list of methods declared in this Class from the cache or JVM as follows:Copy the code

Where reflectionData() is implemented as follows:Copy the code

There is an important data structure called ReflectionData, which is used to cache the following property data for classes read from the JVM:Copy the code

As you can see from the reflectionData() method implementation: 1) reflectionData object is SoftReference type that could be recycled when memory tension, but also can pass - XX: SoftRefLRUPolicyMSPerMB parameters control the timing of the recovery, as long as the GC will be its recovery. 2) if reflectionData is collected and the reflection method is executed, the newReflectionData method can only be used to create such an object.Copy the code

Through unsafe.com pareAndSwapObject method resetting reflectionData field; In privateGetDeclaredMethods approach, if by reflectionData () to obtain reflectionData object is not null, then try to get declaredMethods from reflectionData object properties, If it is the first time, or after GC collection, the class attribute is null after reinitialization, then the JVM needs to fetch it again and assign the value to ReflectionData, and the cache data can be used for the next call.Copy the code

3. Method calls

Once we get the specified Method object Method, we can call its invoke Method, which implements the following:Copy the code

Should be noted: The MethodAccessor object here is the key to the invoke method implementation. MethodAccessor is null at first and a new MethodAccessor object needs to be generated by calling acquireMethodAccessor. MethodAccessor is itself an interface that implements the following:Copy the code

In the acquireMethodAccessor method, newMethodAccessor of the ReflectionFactory class creates an object that implements the MethodAccessor interface as follows:Copy the code

In the ReflectionFactory class, there are two important fields: NoInflation (default false) and inflationThreshold(default 15), In checkInitted approach can pass - Dsun. Reflect. InflationThreshold = XXX and - Dsun. Reflect the noInflation = true to these two fields to reset, and will be set only once;Copy the code

If noInflation to false, the method newMethodAccessor will return DelegatingMethodAccessorImpl object, DelegatingMethodAccessorImpl class implementsCopy the code

Actually, DelegatingMethodAccessorImpl object is a proxy object, is responsible for calling the agent for the delegate object invoke method, including the delegate parameter is NativeMethodAccessorImpl object, So the invoke Method of the final Method calls the Invoke Method of the NativeMethodAccessorImpl object, which is implemented as follows:Copy the code

The inflationThreshold in the ReflectionFactory class is used here. After the Delegate calls the Invoke method 15 times, If you continue, generate a MethodAccessorImpl object from the generateMethod Method of the MethodAccessorGenerator class and set it as a delegate object so that the next time you invoke method.invoke, Call the invoke() method of the newly created MethodAccessor object.Copy the code

4, need to pay attention

When generateMethod generates a MethodAccessorImpl object, it generates the corresponding bytecode in memory and calls ClassDefiner. DefineClass to create the corresponding class object as follows:Copy the code

In the ClassDefiner. DefineClass method implementation, a DelegatingClassLoader object is generated each time it is calledCopy the code

Here every time to generate a new class loader, for performance reasons, in some cases can uninstall these generated classes, because the unloading class is only in the class loader can be recycled will be recycled, if use the original class loader, it may lead to the newly created class has been unable to be unloaded, By design, you don't want these classes to be in memory all the time, just when you need them.Copy the code