跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Java注解(Annotation)的原理是什么_自定义注解与元注解应用

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 有用,运行时完全不可见 运行时读取注解靠反射,但性能有代价 注解本身不执行逻辑,真正干活的是你写的处理代码,通常基于反射遍历类/方法/字段再提取注解。这个过程在类加载或首次调用时发生,会带来开销。 Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 不要在高频方法(如
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 范畴,和运行时反射完全隔离 别把业务逻辑塞进注解接口里——注解里不能写方法体,所有行为必须外置,这是很多人设计混乱的根源 注解不是魔法,它只是把配置从 XML 或 builder 搬到了代码元素旁边;真正难的是怎么让这套标记被正确识别、安全传递、高效消费——尤其是跨模块或框架集成时,
RetentionPolicy
和
ClassLoader
可见性稍不注意,注解就“消失”了。

相关文章