How are annotations implemented in Java
Create the annotation class Inter:
Create Test class Test:
Set the breakpoint in the second sentence of the program, you can see:
As you can see, the instance of the annotation is an object of a dynamic proxy class.
To view the dynamic proxy class, add it to the code
System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Copy the code
Add the system agent and export it as a class file
You can see the following two files:
Decompile $proxy1.class as follows:
As you can see, the dynamic proxy class is the annotation implementation class we defined, decompilating Inner. Class as follows:
As you can see, annotations interface inherits the Java. Lang. The annotation. The annotation, by looking at the source, the source code is as follows:
As you can see, the methods under this class are implemented by the $Proxy1 dynamic proxy class.
So far, we’ve seen that Inner annotations are a special interface that inherits the Annotation interface, and when we get annotations through reflection, we return the dynamic proxy object $Proxy1 generated by the Java runtime, which is the implementation class for Inner annotations.
So how does a proxy class handle method calls?
As we know, calls to dynamic proxy methods are eventually passed to the Invoke method of the bound InvocationHandler instance for processing. We can look at $Proxy1 source code
The statement calls a member variable of the parent class, which is Proxy, as follows:
As you can see, the H object type is one of the implementation classes of the InvocationHandler interface
We set a breakpoint in the constructor of the Proxy class:
The breakpoint can be used to see which object H is:
As you can see, the dynamic proxy classes for AnnotationInvocationHandler object, see the invoke method is as follows:
Where the memberValues variable is the method name key and the variable value, as follows:
So, where does the memberValues variable come from?
As you can see, it is set in the constructor.
Decompile our Test class and see:
So there is a class that is responsible for creating a proxy object AnnotationInvocationHandler, the variable from the constant pool and create the map, and then create a proxy object, this class is AnnotationParser, don’t dwell on here, Interested in their own breakpoint debugging view.
conclusion
Annotations are essentially a special interface that inherits annotations, implemented by dynamic proxy classes generated by the Java runtime. Through a proxy object call custom annotations (interface) method, will eventually call AnnotationInvocationHandler invoke method. This method indexes the corresponding value from the Map memberValues. The source of memberValues is the Java constant pool.