java注解本质是继承annotation的特殊接口,需用元注解声明作用位置和生命周期,运行时通过反射读取,但需配套处理器才能生效。

注解本质是接口,不是“高级注释”
Java 注解不是编译器忽略的普通注释,而是编译后仍保留在 .class 文件里的特殊接口——它自动继承 java.lang.annotation.Annotation,反编译后能看到 interface MyAnnotation extends Annotation。这意味着:你不能 new 它,也不能直接调用方法,只能通过反射获取实例。
- 写
@interface就是在定义一个接口,不是语法糖,是 JVM 层面的约定 - 注解字段只能是基本类型、
String、Class、枚举、其他注解,或以上类型的数组;不支持泛型、lambda、null 默认值 - 没加
@Retention(RetentionPolicy.RUNTIME)的注解,默认只到CLASS阶段,运行时getAnnotations()拿不到,这是最常踩的空指针坑
@Target 和 @Retention 必须配对使用才有效
自定义注解光声明没用,必须用元注解明确“能标在哪”和“活到什么时候”。比如想让注解在 Spring AOP 中生效,就得保证它能被运行时读取,并且允许标在方法上。
-
@Target({ElementType.METHOD, ElementType.TYPE}):表示只能用在方法或类上;若漏写ElementType.METHOD却标在方法上,编译直接报错Invalid type for the annotation -
@Retention(RetentionPolicy.RUNTIME):缺了它,Method.getAnnotation(MyAnnotation.class)永远返回null,哪怕代码里明明写了 - 常见误配:
@Retention(RetentionPolicy.SOURCE)+@Target(ElementType.METHOD)—— 这种组合只对 IDE 或 Lombok 有用,运行时完全不可见
运行时读取注解靠反射,但性能有代价
注解本身不执行逻辑,真正干活的是你写的处理代码,通常基于反射遍历类/方法/字段再提取注解。这个过程在类加载或首次调用时发生,会带来开销。
家电公司网站源码是一个以米拓为核心进行开发的家电商城网站模板,程序采用metinfo5.3.9 UTF8进行编码,软件包含完整栏目与数据。安装方法:解压上传到空间,访问域名进行安装,安装好后,到后台-安全与效率-数据备份还原,恢复好数据后到设置-基本信息和外观-电脑把网站名称什么的改为自己的即可。默认后台账号:admin 密码:132456注意:如本地测试中127.0.0.1无法正常使用,请换成l
- 不要在高频方法(如
toString()、getter)里反复调用getAnnotation();应提前缓存解析结果 - Spring 的
@Autowired、@Value都是在 Bean 创建阶段集中扫描一次,而不是每次注入都反射查找 - 注意
isAnnotationPresent()比getAnnotation()轻量,如果只需要判断存在性,别多拿对象
自定义注解+处理器才是闭环,光写注解没意义
写完 @MyLog 不代表日志就自动打了,你还得配套写逻辑:可能是 Spring 的 @Aspect 切面,也可能是 Java Agent 或编译期 APT 工具。没有消费者,注解就是死标签。
立即学习“Java免费学习笔记(深入)”;
- 最简运行时处理示例:
if (method.isAnnotationPresent(MyLog.class)) { log.info("called: " + method.getName()); } - 若想编译期校验(比如检查参数非空),得用
javax.annotation.processing.Processor+@SupportedAnnotationTypes,这属于 APT 范畴,和运行时反射完全隔离 - 别把业务逻辑塞进注解接口里——注解里不能写方法体,所有行为必须外置,这是很多人设计混乱的根源
RetentionPolicy 和 ClassLoader 可见性稍不注意,注解就“消失”了。









