注解声明必须用@interface而非interface,自动继承Annotation接口;成员只能是无参方法,返回值限基本类型、String、Class、枚举、注解及对应数组;@Target和@Retention需配对使用,RUNTIME保留策略方可反射获取;成员默认值须用default关键字指定。

注解声明必须用 @interface,不是 interface
Java 注解本质是接口的特殊形式,但语法上不能写成普通接口。直接写 interface MyAnnotation 会编译失败,必须加 @ 符号:@interface MyAnnotation。这个 @ 不是修饰符,而是语法标记,告诉编译器这是注解类型。
常见错误:把注解当成普通类或接口去继承、实现,或者漏掉 @ 导致 cannot find symbol 报错。
-
@interface声明的类型自动继承java.lang.annotation.Annotation,不可显式 extends 或 implements - 注解内只能定义方法(即成员),不能有字段、构造器、静态块等
- 每个方法不能有参数,也不能有 throws 子句,返回值类型仅限:基本类型、
String、Class、枚举、其他注解,或以上类型的数组
@Target 和 @Retention 是最常配对使用的元注解
没有 @Target,自定义注解默认可加在任意位置(类、方法、字段等),但多数场景需要限制作用域;没有 @Retention,注解默认只保留在源码阶段(RetentionPolicy.SOURCE),运行时无法反射读取——这点极易被忽略。
典型组合:
立即学习“Java免费学习笔记(深入)”;
微信小程序公众号SaaS管理系统是一款完全开源的微信第三方管理系统,为中小企业提供最佳的小程序集中管理解决方案。可实现小程序的快速免审核注册(免300元审核费),可批量发布小程序模板,同步升级版本等功能。基础版本提供商城和扫码点餐两种小程序模板。商户端可以实现小程序页面模块化设计和自动生成小程序源代码并直接发布。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
-
@Target的值是ElementType枚举,常用值包括TYPE(类)、METHOD、FIELD、PARAMETER、ANNOTATION_TYPE(用于元注解自身) -
@Retention决定注解生命周期:SOURCE(仅源码)、CLASS(字节码中存在但 JVM 不加载)、RUNTIME(可通过反射获取) - 若要用
Class.getAnnotation()或Method.getAnnotation()读取,@Retention必须设为RUNTIME
注解成员默认值必须用 default 关键字,且不能为 null
注解成员像方法一样声明,但支持默认值。不写 default 就是必填项;写了却没提供值,编译报错 annotation member must have a default value。更关键的是:基本类型不能设为 null,而引用类型默认值若不显式写 default null,编译器会拒绝(除非是数组,可写 default {})。
@interface Retryable {
String value() default "";
int maxAttempts() default 3;
Class extends Throwable>[] retryOn() default {};
long backoffMs() default 1000;
}
- 字符串默认空串比
null更安全,避免反射取值后 NPE - 数组成员默认值必须写
default {},不能省略或写null - 枚举、Class 类型成员可写
default Void.class或default MyEnum.DEFAULT,但不能写default null(编译不通过)
元注解本身也是注解,可被其他元注解修饰
比如 @Target 这个元注解,它自己就用了 @Target({ElementType.ANNOTATION_TYPE}) —— 表示它只能用在注解上。这种“注解的注解”就是元注解的递归体现。
实际开发中容易忽略的是:如果你写了一个元注解(如自定义 @Documented 风格的注解),它也需要被 @Target 和 @Retention 修饰,否则无法正常使用。
-
@Documented:标记后,Javadoc 会把该注解包含进生成文档 -
@Inherited:仅对类生效,表示子类自动继承父类的该注解(方法/字段不继承) -
@Repeatable:让同一位置可重复使用该注解,需配套定义容器注解(且容器注解的成员必须是该注解类型的数组)
复杂点在于 @Repeatable 的容器命名和类型匹配必须严格一致,稍有偏差(比如数组类型写错、容器名大小写不对)就会导致 malformed repeatable annotation 错误。









