Java 什么是注解及注解原理详细介绍
这里有新鲜出炉的 Java 函数式编程, 程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言, 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台 (即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)) 的总称
这篇文章主要介绍了 Java 注解的原理实例详解的相关资料, 需要的朋友可以参考下
Java 注解的原理
java : 注解使用,/article/17/1108/359006.html
什么是注解
注解也叫元数据, 例如我们常见的 @Override 和 @Deprecated, 注解是 JDK1.5 版本开始引入的一个特性, 用于对代码进行说明, 可以对包类接口字段方法参数局部变量等进行注解它主要的作用有以下四方面:
生成文档, 通过代码里标识的元数据生成 javadoc 文档
编译检查, 通过代码里标识的元数据让编译器在编译期间进行检查验证
编译时动态处理, 编译时通过代码里标识的元数据动态处理, 例如动态生成代码
运行时动态处理, 运行时通过代码里标识的元数据动态处理, 例如使用反射注入实例
一般注解可以分为三类:
一类是 Java 自带的标准注解, 包括 @Override@Deprecated 和 @SuppressWarnings, 分别用于标明重写某个方法标明某个类或方法过时标明要忽略的警告, 用这些注解标明后编译器就会进行检查
一类为元注解, 元注解是用于定义注解的注解, 包括 @Retention@Target@Inherited@Documented,@Retention 用于标明注解被保留的阶段,@Target 用于标明注解使用的范围,@Inherited 用于标明注解可继承,@Documented 用于标明是否生成 javadoc 文档
一类为自定义注解, 可以根据自己的需求定义注解, 并可用元注解对自定义注解进行注解
注解原理:
看看在 Java 的大体系下面是如何对注解的支持的还是回到上面自定义注解的例子, 对于注解 Test, 如下, 如果对 AnnotationTest 类进行注解, 则运行时可以通过 AnnotationTest.class.getAnnotation(Test.class)获取注解声明的值, 从上面的句子就可以看出, 它是从 class 结构中获取出 Test 注解的, 所以肯定是在某个时候注解被加入到 class 结构中去了
- @Test("test")
- public class AnnotationTest {
- public void test(){
- }
- }
从 java 源码到 class 字节码是由编译器完成的, 编译器会对 java 源码进行解析并生成 class 文件, 而注解也是在编译时由编译器进行处理, 编译器会对注解符号处理并附加到 class 结构中, 根据 jvm 规范, class 文件结构是严格有序的格式, 唯一可以附加信息到 class 结构中的方式就是保存到 class 结构的 attributes 属性中我们知道对于类字段方法, 在 class 结构中都有自己特定的表结构, 而且各自都有自己的属性, 而对于注解, 作用的范围也可以不同, 可以作用在类上, 也可以作用在字段或方法上, 这时编译器会对应将注解信息存放到类字段方法自己的属性上
在我们的 AnnotationTest 类被编译后, 在对应的 AnnotationTest.class 文件中会包含一个 RuntimeVisibleAnnotations 属性, 由于这个注解是作用在类上, 所以此属性被添加到类的属性集上即 Test 注解的键值对 value=test 会被记录起来而当 JVM 加载 AnnotationTest.class 文件字节码时, 就会将 RuntimeVisibleAnnotations 属性值保存到 AnnotationTest 的 Class 对象中, 于是就可以通过 AnnotationTest.class.getAnnotation(Test.class)获取到 Test 注解对象, 进而再通过 Test 注解对象获取到 Test 里面的属性值
这里可能会有疑问, Test 注解对象是什么? 其实注解被编译后的本质就是一个继承 Annotation 接口的接口, 所以 @Test 其实就是 public interface Test extends Annotation, 当我们通过 AnnotationTest.class.getAnnotation(Test.class)调用时, JDK 会通过动态代理生成一个实现了 Test 接口的对象, 并把将 RuntimeVisibleAnnotations 属性值设置进此对象中, 此对象即为 Test 注解对象, 通过它的 value()方法就可以获取到注解值
Java 注解实现机制的整个过程如上面所示, 它的实现需要编译器和 JVM 一起配合
来源: http://www.phperz.com/article/18/0209/359005.html