Java元注解
发布日期:2021-09-29 01:26:55 浏览次数:6 分类:技术文章

本文共 3824 字,大约阅读时间需要 12 分钟。

元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种。

1.@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE)   //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
首 先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。


2.@Target:定义注解的作用目标
源码为:
@Documented  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.ANNOTATION_TYPE)  
public @interface Target {  
    ElementType[] value();  
}  
@Target(ElementType.TYPE)   //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR)  //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包    
3.@Document:说明该注解将被包含在javadoc中
4.@Inherited:说明子类可以继承父类中的该注解
举例:

// 适用类、接口(包括注解类型)或枚举  @Retention(RetentionPolicy.RUNTIME)  @Target(ElementType.TYPE)  public @interface ClassInfo {      String value();  }      // 适用field属性,也包括enum常量  @Retention(RetentionPolicy.RUNTIME)  @Target(ElementType.FIELD)  public @interface FieldInfo {      int[] value();  }  // 适用方法  @Retention(RetentionPolicy.RUNTIME)  @Target(ElementType.METHOD)  public @interface MethodInfo {      String name() default "long";      String data();      int age() default 27;  }

这3个注解分别适用于不同的元素,并都带有不同的属性,在使用注解是需要设置这些属性值。
再定义一个测试类来使用这些注解:

@ClassInfo("Test Class")  public class TestRuntimeAnnotation {       @FieldInfo(value = {1, 2})      public String fieldInfo = "FiledInfo";       @FieldInfo(value = {10086})      public int i = 100;       @MethodInfo(name = "BlueBird", data = "Big")      public static String getMethodInfo() {          return TestRuntimeAnnotation.class.getSimpleName();      }  }  在代码中获取注解信息:private void _testRuntimeAnnotation() {      StringBuffer sb = new StringBuffer();      Class
cls = TestRuntimeAnnotation.class; Constructor
[] constructors = cls.getConstructors(); // 获取指定类型的注解 sb.append("Class注解:").append("\n"); ClassInfo classInfo = cls.getAnnotation(ClassInfo.class); if (classInfo != null) { sb.append(Modifier.toString(cls.getModifiers())).append(" ") .append(cls.getSimpleName()).append("\n"); sb.append("注解值: ").append(classInfo.value()).append("\n\n"); } sb.append("Field注解:").append("\n"); Field[] fields = cls.getDeclaredFields(); for (Field field : fields) { FieldInfo fieldInfo = field.getAnnotation(FieldInfo.class); if (fieldInfo != null) { sb.append(Modifier.toString(field.getModifiers())).append(" ") .append(field.getType().getSimpleName()).append(" ") .append(field.getName()).append("\n"); sb.append("注解值: ").append(Arrays.toString(fieldInfo.value())).append("\n\n"); } } sb.append("Method注解:").append("\n"); Method[] methods = cls.getDeclaredMethods(); for (Method method : methods) { MethodInfo methodInfo = method.getAnnotation(MethodInfo.class); if (methodInfo != null) { sb.append(Modifier.toString(method.getModifiers())).append(" ") .append(method.getReturnType().getSimpleName()).append(" ") .append(method.getName()).append("\n"); sb.append("注解值: ").append("\n"); sb.append("name: ").append(methodInfo.name()).append("\n"); sb.append("data: ").append(methodInfo.data()).append("\n"); sb.append("age: ").append(methodInfo.age()).append("\n"); } } System.out.print(sb.toString()); }

转载地址:https://blog.csdn.net/happydecai/article/details/80216402 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java中子类覆盖父类方法所必须满足的条件
下一篇:java编译错误但是能运行(编译错误不代表不能运行)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月16日 10时37分21秒