497. Java 反射 - 使用反射读取注解
文章目录497. Java 反射 - 使用反射读取注解1. 为什么要关心注解2. 获取注解的工具类AnnotatedElement3. 示例类级别注解4. 示例重复注解 (Repeatable Annotations)方式一通过容器注解 Validators方式二直接用 getAnnotationsByType()5. 总结497. Java 反射 - 使用反射读取注解1. 为什么要关心注解在现代 Java 开发中注解已经成为框架和库的“开关”。ORM 框架如 Hibernate、JPA用注解标记实体字段和表的映射。Spring用注解实现依赖注入、事务管理、安全控制。验证框架用注解标记参数是否允许null、是否必须符合某种格式。 注解之所以能发挥作用核心原因就是运行时通过反射 API 读取注解并执行相应逻辑。2. 获取注解的工具类AnnotatedElement以下几个反射类都实现了AnnotatedElement接口Class类、接口、枚举、记录、数组Field字段Method方法Constructor构造函数它们提供了几组关键方法isAnnotationPresent(Class?)是否存在某个注解。getAnnotations()获取该元素上的所有注解包括继承的。getDeclaredAnnotations()只获取该元素本身声明的注解。getAnnotation(Class?)获取指定类型的注解实例。getAnnotationsByType(Class?)获取重复注解。3. 示例类级别注解定义枚举和注解enumSerializedFormat{BINARY,XML,JSON}Target(ElementType.TYPE)Retention(RetentionPolicy.RUNTIME)interfaceBean{}Target(ElementType.TYPE)Retention(RetentionPolicy.RUNTIME)interfaceSerialized{SerializedFormatformat()defaultSerializedFormat.JSON;}在类上使用SerializedBeanpublicclassPerson{}通过反射读取Class?cPerson.class;booleanisBeanc.isAnnotationPresent(Bean.class);System.out.println(isBean isBean);Annotation[]annotationsc.getAnnotations();for(Annotationannotation:annotations){System.out.println(annotation annotation);}输出isBeantrueannotationorg.devjava.Serialized(formatJSON)annotationorg.devjava.Bean() 注意返回的其实是注解类的实例对象你可以直接调用它的方法。Serializedserializedc.getAnnotation(Serialized.class);System.out.println(format serialized.format());输出formatJSON4. 示例重复注解 (Repeatable Annotations)定义验证规则enumValidationRules{NON_NULL,NON_EMPTY,NON_ZERO}Target(ElementType.FIELD)Retention(RetentionPolicy.RUNTIME)interfaceValidators{Validator[]value();}Target(ElementType.FIELD)Repeatable(Validators.class)interfaceValidator{ValidationRulesvalue();}应用在Person类的字段上publicclassPerson{Validator(ValidationRules.NON_NULL)Validator(ValidationRules.NON_EMPTY)privateStringname;}读取注解方式一通过容器注解ValidatorsFieldnameFieldPerson.class.getDeclaredField(name);Annotation[]annotationsnameField.getAnnotations();Validatorsvalidators(Validators)annotations[0];for(Validatorv:validators.value()){System.out.println(validator v);}输出validatororg.devjava.Validator(NON_NULL)validatororg.devjava.Validator(NON_EMPTY)方式二直接用getAnnotationsByType()Validator[]validatorsnameField.getAnnotationsByType(Validator.class);for(Validatorv:validators){System.out.println(annotation v);}输出annotationorg.devjava.Validator(NON_NULL)annotationorg.devjava.Validator(NON_EMPTY) 第二种方式更简洁JDK 会自动帮你展开容器注解。5. 总结注解是框架的“说明书”框架通过反射读取注解来决定如何运行。类、方法、字段、构造函数都可以携带注解并通过AnnotatedElement访问。isAnnotationPresent()检查是否存在。getAnnotation()获取单个注解。getAnnotationsByType()用于重复注解。