Java注解的底层结构竟然是Map,这究竟是怎么回事?

摘要:案例介绍 案例一:普通注解用法 下面的代码定义了一个注解 @Test,然后在 AnnotationTest 中获取到这个注解,然后打印出它 value() 方法的值。 @Retention(RetentionPolicy.RUNTIME)
案例介绍 案例一:普通注解用法 下面的代码定义了一个注解 @Test,然后在 AnnotationTest 中获取到这个注解,然后打印出它 value() 方法的值。 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Test { String value() default ""; } @Test("test") public class AnnotationTest { public static void main(String[] args) { Test test = AnnotationTest.class.getAnnotation(Test.class); System.out.println(test.value()); } } 执行上面的代码,结果输出如下: 案例二:组合注解用法 下面的代码中尝试从某个类上获取它的注解,然后再从这个注解中获取它上面的注解。组合注解在 Spring 中很常见,比如常用的 @RestController,它实际上就是组合了 @Controller 和 @ResponseBody 这两个注解。 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Test { String value() default ""; } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Test("composite") public @interface TestComposite { } @TestComposite public class AnnotationTest { public static void main(String[] args) { TestComposite testComposite = AnnotationTest.class.getAnnotation(TestComposite.class); boolean existInProxyObj = testComposite.getClass().isAnnotationPresent(Test.class); System.out.println("是否在动态代理对象的Class对象上存在:" + existInProxyObj); boolean existInOriginal = testComposite.annotationType().isAnnotationPresent(Test.class); System.out.println("是否在原始的Class对象上存在:" + existInOriginal); } } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController { @AliasFor(annotation = Controller.class) String value() default ""; } 执行上面的代码,结果输出如下: 可以看到执行结果在 testComposite.getClass() 返回的 Class 对象上不存在 @Test 这个注解,而是在 testComposite.annotationType() 返回的 Class 对象上才存在 @Test 这个注解。这个问题的原理是什么呢? 先说下结论: 使用 @interface 定义了一个注解之后编译得到的 class 文件会默认继承 @Annotation 这个接口; 在代码中获取注解时实际上是获取到的是 JDK 为它创建的一个动态代理对象。
阅读全文