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 为它创建的一个动态代理对象。
