【Java初学基础11】Annotation-注解
一、注解是什么
注解(Annotation)是一种 元数据(metadata),用来修饰代码(类、方法、字段、参数、包等)。
不直接影响程序逻辑,但可以被 编译器、工具 或 运行时框架 读取并执行特定逻辑。
主要作用:
提供信息给编译器(如抑制警告
@SuppressWarnings
)。在编译阶段处理(APT,Annotation Processing Tool)。
在运行时处理(通过反射获取)。
二、常见的内置注解
Java 提供了一些内置注解,最常见的有:
编译检查相关
@Override
:检查方法是否正确重写父类方法。@Deprecated
:标记过时方法,编译器会警告。@SuppressWarnings("unchecked")
:抑制警告信息。
元注解(用来修饰注解本身的注解)(只列举两个最常用的元注解)
@Target
:指定注解能放在哪些元素上(类、方法、字段等)。(通常用枚举类来声明)@Retention
:指定注解的保留范围(源码、字节码、运行时)。
三、注解的生命周期(Retention Policy)
SOURCE:只在源码中存在,编译后丢弃(如
@Override
)。CLASS:编译进字节码,但运行时不可见(默认)。
RUNTIME:编译进字节码,运行时可通过反射读取(Spring、JPA 常用)。
①
RetentionPolicy.SOURCE
注解 只存在于源码 中,编译后不会进入
.class
文件。编译器可利用它做检查,但运行时完全无效。
典型例子:
@Override
,@SuppressWarnings
。所以说重写方法时可以不用写@Override注解
②
RetentionPolicy.CLASS
注解会被编译进
.class
文件,但 JVM 加载后丢弃。默认值。
在字节码分析工具可能会用到,但运行时不能通过反射读取。
③
RetentionPolicy.RUNTIME
注解编译后仍然保留到 JVM 运行时。
可以通过 反射 获取到注解信息。
框架开发(Spring、Hibernate、JUnit)常用。
通过反射机制读取注解
//注意这个注解生命周期是RUNTIME:写进字节码,并且 JVM 加载后保留在内存里,供反射 API 使用。
@RuntimeAnnotation("Hello")
public class Test {}public class Main {public static void main(String[] args) {
//获取字节码文件Class<Test> clazz = Test.class;if (clazz.isAnnotationPresent(RuntimeAnnotation.class)) {RuntimeAnnotation ann = clazz.getAnnotation(RuntimeAnnotation.class);System.out.println(ann.value()); // 输出 Hello}}
}
四、自定义注解
你可以自己定义注解,用来给代码加标记,框架再通过 反射 处理。
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) // 运行时可见
@Target({ElementType.METHOD, ElementType.TYPE}) // 可用在类和方法上public @interface MyAnnotation { String value(); int version() default 1; // 默认值 }
@MyAnnotation(value = "测试注解", version = 2)
public class Test {@MyAnnotation("方法注解") public void doSomething() {} }
Class<?> clazz = Test.class;
if (clazz.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation ann = clazz.getAnnotation(MyAnnotation.class); System.out.println(ann.value() + " - v" + ann.version()); }
五、注解在框架中的应用
Java 注解在现代框架中用得非常广泛。如今的程序开发已经成长为面向注解开发。
Spring
@Component
,@Service
,@Controller
,@Repository
(组件扫描)@Autowired
(依赖注入)@Configuration
,@Bean
(配置类和 Bean 定义)
JUnit
@Test
,@Before
,@After
Servlet
@WebServlet("/path")
它们基本上都是 运行时注解,通过反射扫描并生效。
总结
在 Java 中,注解是一种元数据机制,它不会直接改变程序逻辑,却能为编译器、工具和框架提供丰富的信息。
内置注解(如
@Override
、@Deprecated
)让我们在编译期就能发现错误或提示。注解的生命周期 决定了它能否被写入字节码,以及能否在运行时通过反射读取:
SOURCE
→ 仅源码CLASS
→ 编译进字节码,运行时丢弃RUNTIME
→ 保留到运行时,可反射获取(框架最常用)
自定义注解 可以通过
@Retention
和@Target
控制生命周期和作用范围,再结合反射获取注解信息,实现灵活扩展。在框架中的应用(如 Spring 的
@Component
、JPA 的@Entity
、JUnit 的@Test
)已经成为现代开发的主流模式,注解驱动让代码更简洁、可读性更强。
👉 总的来说,注解就是让 Java 代码“自带说明书”,编译器和框架正是通过它来实现编译检查、自动配置和运行时行为扩展。