When I was learning Spring Aop, I learned that the underlying implementation of spring is basically annotation plus reflection.It's like writing your own very small test code and trying it out.But there are some minor episodes in the process.
I want to invoke the @Tag marked part of the method held by an object through reflection. Here is my code:
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.reflect.Method; import java.lang.annotation.RetentionPolicy; public class Test { public static void main(String[] args) throws Exception { Class<Test> t=Test.class; //Get Class Object Method[] m=t.getMethods(); //Get a collection of methods for(Method mm : m) { //traversal method if(mm.toString().contains("m(")) //Printing Test Method System.out.println("\nmethod print:\t"+mm); for(Annotation a : mm.getAnnotations()) { //Traversal Method Notes if((a.getClass()==Tag.class)) { System.out.print("method invoke:\t"); mm.invoke(new Test(), 666); //Call Method } } } } @Tag //test method public void m(int n) { System.out.println("method m(int n): "+n); } @Tag2 public void m(double n) { System.out.println("method m(double n): "+n); } } @Retention(RetentionPolicy.RUNTIME) //Test Notes @interface Tag{} @Retention(RetentionPolicy.RUNTIME) @interface Tag2{}
But the output of this program is not what I want to see, as shown below, and the invoke() method did not execute
Since the method m(int) marked by @Tag was not called, I used to view the output of the following statement
System.out.println("a.getClass()\t"+a.getClass()); System.out.println("Tag.class\t"+Tag.class);
Errors are quickly defined to the line if((a.getClass()==Tag.class)).A.getClass(), A is an example of the annotation we get by traversing the annotation collection (getAnnotations) of the Test.m() method.So a instanceof Annotation should be true.(tested, true)
On the other hand, we know that Annotation is a special Interface interface, so annotations cannot be instantiated.This printout, class test2.$Proxy1, makes sense (test2 is the current package name), that is, when the JVM calls getAnnotation, it automatically generates the @Tag annotated implementation class (anonymous class) and returns an instance of the class
In other words, can annotations also be implemented?
I typed the code in eclipse with a validated mind:
import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; public class Test4 { public static void main(String[] args) { Annotation annotation = new ttttt(); System.out.println(annotation.getClass()); System.out.println(annotation.annotationType()); } } @Retention(RetentionPolicy.RUNTIME) @interface Tag4{} class ttttt implements Tag4{ //When implements Tag4 is written out, the @Override method is automatically prompted to be added @Override public Class<? extends Annotation> annotationType() { return Tag4.class; } }
True as the above conjecture.
So go back to the original question.What should we do if getClass() is invalid if we want to call a method annotated by @Tag
In fact, the problem is much simpler. Knock annotation. Look at the tip and you know there is one way to do this: annotation Type ()
Change the code to:
for(Annotation a : mm.getAnnotations()) { if(a.annotationType()==Tag.class) { System.out.print("method invoke:\t"); mm.invoke(new Test(), 666); } }