当前位置: 代码迷 >> 综合 >> 4Java反射与泛型——2注解——3处理注解(廖雪峰)
  详细解决方案

4Java反射与泛型——2注解——3处理注解(廖雪峰)

热度:58   发布时间:2024-02-08 06:17:39.0

1Annotation

  • 注解本身对对代码逻辑没有任何影响
  • SOURCE类型的注解在编译期就被丢掉了
  • CLASS类型的注解仅保存在class文件中
  • RUNTIME类型的注解在运行期可以被读取
  • 如何使用注解由工具决定
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {int type() default 0;String level() default "info";String value() default "";
}@Report(type=1,level="error")
public class Person {}

因此如何处理注解只针对RUNTIME类型的注解

如何读取RUNTIME类型的注解

如何读取RUNTIME类型的注解?

  • Annotation也是class
  • 所有Annotation继承自java.lang.annotation.Annotation
  • 使用反射API读取Annotation
    • 方法1: 判断某个Annotation是否存在,存在再打印注解的信息
      • Class.isAnnotationPresent(Class)
      • Field.isAnnotationPresent(Class)
      • Method.isAnnotationPresent(Class)
      • Constructor.isAnnotationPresent(Class)
    • 方法2:获取某个Annotation,注解对象不为空,再打印注解的信息
      • Class.getAnnotation(Class)
      • Field.getAnnotation(Class)
      • Method.getAnnotation(Class)
      • Constructor.getAnnotation(Class)
      • getParameterAnnotations()
Class cls = Person.class;
//判断@Report是否存在
cls.isAnnotationPresent(Report.class)Class cls = Person.class;
//获取Report的Annotation
Report report = cls.getAnnotation(Report.class);
int type = report.type();
String level = report.level();
//方法一:判断Annotation是否存在再读取
Class cls = Person.class;
if (cls.isAnnotationPresent(Report.class)) {Report report = cls.getAnnotation(Report.class);...
}//直接使用getAnnotation获取
Class cls = Person.class;
Report report = cls.getAnnotation(Report.class);
if(report != null){...
}

2读取方法参数的Annotation

public class Main {public static void main(String[] args) throws Exception{Person p1 = new Person("Xiao Ming", 25);Person p2 = new Person(null, 15);checkPerson(p1);checkPerson(p2);}static void checkPerson(Person p) throws Exception{System.out.println("check " + p + "...");Class c = Person.class;for (Field f : c.getFields()) {checkField(f,p);}}static void checkField(Field f, Person p) throws Exception{if (f.isAnnotationPresent(NotNull.class)) {Object r = f.get(p);if (r==null) {System.out.println("Error:field " + f.getName() + " is null...");}}if (f.isAnnotationPresent(Range.class)) {Range range = f.getAnnotation(Range.class);int n = (Integer) f.get(p);if (n < range.min() || n > range.max()) {System.out.println("Error:field " + f.getName() + " is out of range...");}}}}
public class Person {@NotNullpublic String name;@Range(max = 20)public int age;public Person(String name,int age) {this.name = name;this.age = age;	}
}
//检查int类型的值在min到max之间
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Range {int min() default 1;int max() default 100;}
//检查字段不为空的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface NotNull {}

3总结

  • 可以在运行期通过反射读取RUNTIME类型的注解,不要漏写@Retention(RetentionPolicy.RUNTIME)
  • 可以通过工具处理注解来实现相应的功能
    •  对JavaBean的属性值按规则进行检查
    • JUnit会自动运行@Test注解的测试方法
  相关解决方案