Constructor-depth understanding of the method newInstance

Know, know why

0. Introduction

On a "reflection from entry to the master of insight into Class class" , our in-depth analysis of what Class principle of class. In this article, we analyze the Constructor using the principle of the method.

1. Constructor

There are two methods by reflection to invoke the constructor:

  • Call the no-argument constructor: Class.newInstance ()
  • Call the constructor with parameters:
    • By Class acquiring class Constructor
    • Call Constructor of newInstance (Object ... initarges) method

Specific can see "the reflection from 0 to Getting Started" , we know these deep knowledge of Constructor of newInstance (Object ... initarges) method.

1.1 newInstance

Want to know principle, the first step is to understand jdk comment, newInstance comments as follows:

(Excuse me, do not understand this whole end of the play ...)

Do not go, I'll give you the translation (Google translated so delicious)

Representative using Constructor constructor creates and initializes an example of a parameter. Each parameter is automatically unpacking parameters to match the form of the original, and the original parameter and the reference parameter have to convert the method call as needed.

To obtain the constructor with no arguments, the length parameter may be null or 0

Call non-static inner classes, parameters. . . (Not translated here)

And parameter access via the check is successful, we will continue to be instantiated. If you declare the class constructor is not initialized, you need to initialize

Constructors completed, returns the newly created and initialized good example

According to Mike this rough translation, we can get a few key elements below:

  • Creating instance initialization parameters, parameter rules match;
  • Get no argument constructor parameter length may be 0 or null;
  • Have access to parameters and checks need to get to declare class constructor;

Knowing this we have to interpret what newInstance () source code, look:

Source can be split into three parts:

  1. Check Permissions: Permissions do not check in this analysis, we can see the source code itself
  2. Gets declaring class constructor
  3. Creating entity

Gets declaring class constructor

Class constructor declaration ConstructorAccessor is an interface, as shown below:

View the next class that implements the interface structure (the dashed line represents the implementation of the interface, the blue line represents the inheritance, the white line is what the hell?)

Understood implementation class are inherited from FIG ConstructorAccessorImpl abstract class, and implements the newInstance () method.

That which implementation class to use that in the end it? We continue to look down

If ConstructorAccessor has been created, acquired and assigned. If not then by newConstructorAccessor creation method ConstructorAccessor . newConstructorAccessor follows:

newConstructorAccessor divided into three parts:

  1. Check whether initialization

This is reflected plant (ReflectionFactory) checking the initialization state, if no initialization will be carried out with the following operations on the red coil.

That probably guess what this is doing it?

First of all, inflation is literally inflation or expansion, that noInflation literal understanding is not expanded.

Threshold is literally the threshold, inflationThreshold literally understand inflation threshold is a limit inflation value.

NoInflation understood literally understood to determine whether the inflation, inflationThreshold inflation is a limit value.

Ask degree of your mother, verify our results:

JNI (Java Native Interface), written using the Java Native Interface program, you can ensure that the code easily portable across different platforms.

Almost guess, the JVM are two ways to access information about the reflection type, or the reader can use JNI Java bytecode accessor. inflationThreshold using JNI is the number of accessor value of 0 indicates no access is read from the JNI. If you want to force the Java bytecode accessor, can noInflation set to true.

inflationThreshold default value is 15 , if not inflationThreshold modification, the JVM information access classes will start reflecting JNI read access control 15 will use the Java bytecode accessor times after

This may explain why there through a detection operation initialized.

From this section you can learn some small knowledge:

We can use the -D = to set the system properties, to acquire the property value by System.getProperty ( "attribute name").

  1. Gets the Class instance of the current class

  1. According to acquire condition ConstructorAccessor

    So much if conditional, do not panic, I'll help you analyze the wave:

    • Step 1, checking the second step in the example of Class acquired is not an abstract class, an abstract class if it is thrown.
    • Step 2, determines whether the Class example, because the constructor Class Examples are private, so this also needs to throw an exception.
    • Step 3, to determine whether the Class instance inheritance ConstructorAccessorImpl , if a parent-child relationship, call BootstrapConstructorAccessorImpl create ConstructorAccessor , this method is a native method call, the local interface with the underlying implementation of c ++.
    • Step 4, if noInflation is true and Class instance is not anonymous, call MethodAccessorGenerator.generateConstructor () to create ConstructorAccessor , specific details are not analyzed, principles or by reading a binary file, will come loaded Class instance, then according to some conditions for access to the desired Constructor .
    • Step 5, the above conditions are not met, call NativeConstructorAccessorImpl , look at the source code of this method:

    The number of calls and inflationThreshold comparison, if more than inflationThreshold (default is 15), the method is not called and the fourth step is the same.

    If less than or equal inflationThreshold , should call newInstance0 method, newInstance0 is a native method call is local interface.

    In fact, the first step is to initialize the time here to pave the way for it.

    Here not get away, there is a DelegatingConstructorAccessorImpl method.

    Well, this one uses a proxy-hand mode, the NativeConstructorAccessorImpl put into DelegatingConstructorAccessorImpl delegate's. newInstance newInstance method call is a delegate.

    Remember the white line I started to ask what to do, this time doubts it.

Content a bit more, I draw a map with you comb:

image link

Create an instance of

Previous to the acquisition ConstructorAccessor implementation class, direct call newInstance method to create an instance.

2. summary

We look back at the previous contents:

First, we According to jdk know annotation provided newInstance may be initialized according to the parameters and returns an instance, you want to get to get to the instance must declare the class constructor ConstructorAccessor , then we have in-depth analysis of the ConstructorAccessor .

ConstructorAccessor there is an abstract class ConstructorAccessorImpl , other implementations class needs to inherit ConstructorAccessorImpl , several implementation class are the following:

  • InstantiationExceptionConstructorAccessorImpl : save up exception information, call newInstance throws InstantiationException exception.

  • BootstrapConstructorAccessorImpl : Class instance and when you need to create ConstructorAccessorImpl is a parent-child relationship, it is necessary to return BootstrapConstructorAccessorImpl , the underlying method is invoked, written by C ++.

  • SerializationConstructorAccessorImpl : is an abstract class, when reading from the JVM Java bytecode will return the implementation class.

  • NativeConstructorAccessorImpl : call the local interface method to create ConstructorAccessor , need to call the number and inflationThreshold comparison, inflationThreshold default value is 15, you can ** - ** to modify the default value Dsun.reflect.inflationThreshold =.

    When the number of calls more than 15 times, JVM were taken from Java bytecode. 12. In contrast, from a local interface.

  • DelegatingConstructorAccessorImpl : proxy class is NativeConstructorAccessorImpl parent.

Get to the ConstructorAccessor , to create an instance by calling the newInstance () method.

Reflection Related Articles

"Reflection from 0 to Getting Started"

"Reflective understanding Class class from entry to the proficient depth"

No public : the Java knowledge school , which has reflected the content I recently put together, hoping to be helpful to everyone.

Guess you like

Origin juejin.im/post/5e00e5a96fb9a0162a0b80f5