注解(Annotation)是代码里的「标记」,本身不改变逻辑,但可以被编译器、工具或反射读取。
1. 常见内置注解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class BuiltInAnnotationDemo { @Override public String toString () { return "这是重写的方法" ; } @Deprecated public void oldMethod () { System.out.println("过时的方法" ); } @SuppressWarnings("unused") public void anotherMethod () { int x = 10 ; } }
2. 自定义注解 用 @interface 定义注解,配合 @Retention 和 @Target 指定它的生命周期和适用范围。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyTest { String value () default "默认值" ; int times () default 1 ; }
3. 使用自定义注解 1 2 3 4 5 6 7 8 9 10 11 public class UseAnnotationDemo { @MyTest(value = "测试登录", times = 2) public void login () { System.out.println("执行登录" ); } @MyTest("测试注册") public void register () { System.out.println("执行注册" ); } }
4. 用反射读取注解 注解配合反射,是很多框架(如 JUnit)的核心机制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.lang.reflect.Method;public class ReadAnnotationDemo { public static void main (String[] args) throws Exception { UseAnnotationDemo demo = new UseAnnotationDemo (); Class <?> cls = demo.getClass(); for (Method m : cls.getDeclaredMethods()) { if (m.isAnnotationPresent(MyTest.class)) { MyTest ann = m.getAnnotation(MyTest.class); System.out.println("运行测试:" + ann.value() + "(执行 " + ann.times() + " 次)" ); for (int i = 0 ; i < ann.times(); i++) { m.invoke(demo); } System.out.println(); } } } }
输出:
1 2 3 4 5 6 运行测试:测试登录(执行 2 次) 执行登录 执行登录 运行测试:测试注册(执行 1 次) 执行注册
5. 元注解 定义注解时用到的注解:
元注解
作用
@Retention
注解保留到什么时候(SOURCE / CLASS / RUNTIME)
@Target
能用在哪些地方(类、方法、字段、参数…)
@Inherited
子类能否继承
@Documented
是否写入文档
小结
常见内置注解:@Override、@Deprecated、@SuppressWarnings
自定义注解用 @interface,配合 @Retention、@Target
注解 + 反射是框架(JUnit、Spring)的核心机制