Java基础:Java 注解(Annotation)及使用
Java 注解(Annotation)是 JDK 1.5 引入的特性,与类、接口、枚举是在同一等级。它可以作用在类、属性、方法、局部变量、方法参数上,用于对这些元素进行说明,注释,解释。
注解在功能上可以看成是一个接口,注解实例就是一个实现该接口的动态代理类,可在方便在程序运行期间通过反射获取该字段或方法的注解的实例,来决定下一步如何处理。
注解定义
注解 是一种标记,一种标注,一个极期相似的比喻就是标签纸,用于对其作用的目标对象进行说明,以便进行对应的操作。
有了注解,还需要对这些注解进行解析,可以通过反射机制(Reflect)访问这些注解并对其进行解析(注解解析类),没有解析的注解不起任何作用,没有任何意义的,但也不会影响代码的执行。
所有 注解 类型都继承 java.lang.annotation.Annotation 公共接口。注解的使用越来越流行,Spring Boot 框架就提供了大量的注解,由 SSM 框架的 XML 配置转为 Java 配置类,注解扮演很重要的角色,非常方便且代码更加简洁。
基本注解
定义注解与定义接口相似,只是在接口名前需要前使用 @ 符号。Java 5 内置了三种基本注解:
- @Override:当前方法重写父类中的方法。
- @Deprecated:标记该目标已被弃用,不建议使用,或存在更好的替代方案。
- @SuppressWarnings:抑制编译器的警告信息。
Java 8 新增了一种注解:
- @Repeatable:支持同一个注解可重复在同一类/方法/属性上使用,更低的版是不支持的。
元注解
元注解 :作用在注解上的注解,编译器自动会对这种类注解进行解析。 JDK 提供的元注解有 @Retention,@Target ,@Documented,@Inherited四个。
Spring 框架提供的很多注解,也使用了元注解。例如 Spring Boot 入口类的注解:
| 1 | 
 | 
@Target
标记此类型的注解应该作用在那种 Java 成员上。该元注解只有一个属性,引用的是 java.lang.annotation.ElementType 枚举中的值。
- @Target - 1 
 2
 3
 4
 5
 6
 public Target {
 ElementType[] value();
 }
- ElementType - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36- public enum ElementType { 
 /**
 * 类,接口,枚举声明
 */
 TYPE,
 /**
 * 字段声明(包括枚举值)
 */
 FIELD,
 /**
 * 方法声明
 */
 METHOD,
 /**
 * 方法参数声明
 */
 PARAMETER,
 /**
 * 构造方法声明
 */
 CONSTRUCTOR,
 /**
 * 局部变量声明
 */
 LOCAL_VARIABLE,
 /**
 * 注解类型声明
 */
 ANNOTATION_TYPE,
 /**
 * 包声明
 */
 PACKAGE,
 TYPE_PARAMETER,
 TYPE_USE
 }
@Retention
标记此类型的注解将保留多长时间(保留级别,或称为注解生命周期)。如果注解没有使用此元注解,则保留策略默认为 RetentionPolicy.CLASS。
该元注解只有一个属性,引用的是 java.lang.annotation.RetentionPolicy 的枚举值。
- @Retention - 1 
 2
 3
 4
 5
 6
 public Retention {
 RetentionPolicy value();
 }
- RetentionPolicy - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17- public enum RetentionPolicy { 
 /**
 * 只在源码中保留,将被编译器丢弃
 */
 SOURCE,
 
 /**
 * 编译时会记录到CLASS文件中,但运行时忽略,默认行为。
 */
 CLASS,
 /**
 * 编译时会记录到CLASS文件中,并在运行时由 JVM 保留,可以通过反射读取它们。
 * @see java.lang.reflect.AnnotatedElement
 */
 RUNTIME
 }
@Document
标记将注解包含在 Javadoc 中。指示默认情况下,javadoc 和类似工具将记录带有此类型的注解,成为公共API 的一部分。
类和方法的注解,在默认情况下是不出现在 javadoc 中的。如果使用 @Document 修饰该注解,则表示此注解会出现在 javadoc 中。
| 1 | 
 | 
@Inherited
标记该注解是具有继承性的,使用该元注解的注解作用的目标类的子类具体父类的注解特性。只能作用在 Annotation 类型上。
| 1 | 
 | 
注解作用
注解的作用大致可分为三类:
- 生成文档:标识目标代码需要生成文档(doc)。
- 代码分析:标识对代码进行解析,使用反射实现。
- 编译检查:标识编译器可对代码进行最基本的编译检查。
注解使用
注解只有一个成员时,按规范写成 value(),当然不这么写也不会报错。如果不设置默认值,那么使用注解时必须要传值。只有类可以被注解,接口或抽象类不能被注解。
自定义注解
自定义一个对用户年龄范围进行校验的注解,实现用户年龄范围的控制和提示。
| 1 | 
 | 
注解解析
- 定义一个用户类 User.class - 1 
 2
 3
 4
 5
 6- public class User { 
 private String name;
 
 private int age;
 }
- 对注解进行解析 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14- public static void main(String[] args) { 
 User user = new User().setAge(11);
 Class<User> userClass = User.class;
 Field[] fieldArray = userClass.getDeclaredFields();
 for (Field field : fieldArray) {
 AgeRange ageRange = field.getDeclaredAnnotation(AgeRange.class);
 if (ageRange != null) {
 if (user.getAge() > ageRange.max() || user.getAge() < ageRange.min())
 System.out.println("用户年龄必须在 18 到 45 之间");
 }
 }
 }
读取注解
| 1 | //读取注解信息 | 
其它参考
Java基础:Java 注解(Annotation)及使用

