Java 注解(Annotation)
📅 2026/7/11 20:15:49
👁️ 阅读次数
📝 编程学习
1. 什么是注解?
注解(Annotation),也叫注释类型,是一种引用数据类型。它和类、接口一样,编译后也会生成.class文件。
注解本身不直接改变程序逻辑,但它可以携带元数据,在编译、类加载、运行时被读取,并配合工具或框架完成特定功能。
2. 自定义注解的语法
自定义注解使用@interface关键字,基本语法如下:
[修饰符列表]@interface注解类型名{// 属性定义}使用注解的语法格式:
@注解类型名注解可以出现的位置:
- 类上(上一行)
- 属性上
- 方法上
- 变量上
- 甚至可以用在注解上
3. JDK 内置注解
java.lang包下提供了几个常用的内置注解:
3.1 @Deprecated
@Deprecated用于标记不推荐使用的程序元素。通常是因为该元素存在危险,或者已有更好的替代方案。
3.2 @Override
@Override表示一个方法声明意图重写父类中的方法。
核心要点:
- 只能注解方法
- 仅供编译器参考,与运行时无关
- 编译器会检查被标注的方法是否确实是重写父类方法,不是则报错
3.3 @SuppressWarnings
@SuppressWarnings用于指示编译器取消显示指定的警告信息。
4. 元注解
元注解是专门用来标注其他注解的注解。
4.1 @Target
@Target指定被标注的注解可以出现在哪些程序元素上。例如:
@Target(ElementType.METHOD)表示被该注解标注的自定义注解只能出现在方法上。
4.2 @Retention
@Retention指定被标注的注解最终保留到哪个阶段。取值如下:
| 取值 | 含义 |
|---|---|
RetentionPolicy.SOURCE | 仅保留在 Java 源文件中 |
RetentionPolicy.CLASS | 保留在 class 文件中,但 JVM 不加载 |
RetentionPolicy.RUNTIME | 保留在 class 文件中,且能被反射机制读取 |
@Retention的源码:
public@interfaceRetention{RetentionPolicyvalue();}publicenumRetentionPolicy{SOURCE,CLASS,RUNTIME}@Target的源码:
public@interfaceTarget{ElementType[]value;// ElementType 是一个枚举}5. 注解中定义属性
在注解中可以定义属性,语法与方法类似:
public@interfaceMyAnnotation{Stringname();// 属性 nameString[]color();// 属性 color,数组类型intage()default18;// 属性 age,指定默认值后使用时可以不赋值int[]no;// 属性 no,数组类型}使用规则:
- 如果注解中有属性,使用时必须给属性赋值(已指定默认值的除外)
- 数组属性只有一个元素时,可以省略花括号
{}
publicclassTest{@MyAnnotation(name="zhangsan",color={"blue","red"},no=1)publicvoiddoSomething(){// age 有默认值,可写可不写}}5.1 属性名为 value 的特殊规则
如果属性名为value,且只有这一个属性时,使用注解可以省略属性名:
public@interfaceMyAnnotation01{Stringvalue();}publicclassTest01{@MyAnnotation01("haha")publicvoiddoSomething(){}}如果有多个属性,则value也必须显式写出属性名。
5.2 属性支持的类型
注解属性可以是以下类型及其数组形式:
- 基本数据类型(int、double、boolean 等)
- String
- Class
- 枚举
- 以上类型的数组
6. 通过反射获取注解
注解可以通过反射机制在运行时读取,前提是@Retention必须设置为RUNTIME。
// 获取类的 Class 对象Classc=Class.forName("完整类名");// 判断该类上是否存在指定注解System.out.println(c.isAnnotationPresent(注解类型名.class));if(c.isAnnotationPresent(注解类型名.class)){// 获取注解对象注解类名 对象名=(注解类型名)c.getAnnotation(注解类型名.class);// 读取注解属性值,就像调用接口方法一样对象名.属性名();}通过反射与注解的配合,可以在运行时动态获取类、方法、字段上的元数据,这是 Spring、JUnit 等框架的核心机制之一。
编程学习
技术分享
实战经验