注解的原理又是怎么一回事

Java内置的注解以及自定义一个注解大家都比较熟悉的了,现在来看看注解实现的原理,看看Java的体系下面是如何对注解的支持的。

在讨论前先看一个自定义注解的例子,自定义实现这样一个注解:通过@Test向某类注入一个字符串,通过@TestMethod向某个方法注入一个字符串。

① 创建Test注解,声明作用于类并保留到运行时,默认值为default。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
    String value() default "default";
}

② 创建TestMethod注解,声明作用于方法并保留到运行时。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TestMethod {
    String value();
}

③测试类,运行后输出default和tomcat-method两个字符串,因为@Test没有传入值,所以输出了默认值,而@TestMethod则输出了注入的字符串。

@Test()
public class AnnotationTest {
    @TestMethod("tomcat-method")
    public void test(){
    }
    public static void main(String[] args){
        Test t = AnnotationTest.class.getAnnotation(Test.class);
        System.out.println(t.value());
        TestMethod tm = null;
        try {
            tm = AnnotationTest.class.getDeclaredMethod("test",null).getAnnotation(TestMethod.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(tm.value());
    }
}

对于注解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一起配合。

====广告时间,可直接跳过====

鄙人的新书《Tomcat内核设计剖析》已经在京东预售了,有需要的朋友可以到 https://item.jd.com/12185360.html 进行预定。感谢各位朋友。

=========================

欢迎关注:

时间: 2024-07-29 00:10:56

注解的原理又是怎么一回事的相关文章

我知道java注解,原理是反射,可是没看出来注解的便利,理解的不好,求大神点化???

问题描述 我知道java注解,原理是反射,可是没看出来注解的便利,理解的不好,求大神点化??? 我知道java注解,原理是反射,可是没看出来注解的便利,理解的不好,求大神点化??? 解决方案 注解的作用好像是把配置文件的内容移动到代码上面来.虽然配置文件是为了减少修改代码,把可能改变的都写在配置文件.但是很多情况是在配置文件配置了后就不会再改变的,这样不如放在代码上面,不用代码和配置文件来回切换. 还有就是只有注解时做不了东西的.是通过反射读取到注解的键值对,然后根据键值对来做相应的事情. 一个

注解的原理

前面介绍了如何使用Java内置的注解以及如何自定义一个注解,接下去看看注解实现的原理,看看在Java的大体系下面是如何对注解的支持的.还是回到上面自定义注解的例子,对于注解Test,如下,如果对AnnotationTest类进行注解,则运行时可以通过AnnotationTest.class.getAnnotation(Test.class)获取注解声明的值,从上面的句子就可以看出,它是从class结构中获取出Test注解的,所以肯定是在某个时候注解被加入到class结构中去了. @Test("t

我的2017年文章汇总——Java及中间件篇

2018即将到来,大家看着2017给自己制定的计划有没有感慨?当你觉得过去一年没有什么进步时,那么请行动起来,能开始总是好的. 近期准备把过去一年写的文章按照分类重新整理推送一遍,包括:"分布式"."机器学习"."深度学习"."NLP"."Java深度"."Java并发核心"."JDK源码"."Tomcat内核". 本篇推送Java及中间件相关文章

注解机制及其原理

什么是注解 注解也叫元数据,例如我们常见的@Override和@Deprecated,注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进行注解.它主要的作用有以下四方面: 生成文档,通过代码里标识的元数据生成javadoc文档. 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证. 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码. 运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入

Spring源码学习之:@async 方法上添加该注解实现异步调用的原理

在我们使用spring框架的过程中,在很多时候我们会使用@async注解来异步执行某一些方法,提高系统的执行效率.今天我们来探讨下 spring 是如何完成这个功能的.     spring 在扫描bean的时候会扫描方法上是否包含@async的注解,如果包含的,spring会为这个bean动态的生成一个子类,我们称之为代理类(?), 代理类是继承我们所写的bean的,然后把代理类注入进来,那此时,在执行此方法的时候,会到代理类中,代理类判断了此方法需要异步执行,就不会调用父类 (我们原本写的b

第二课笔记:搜索引擎基础知识和工作原理

  大家好,我是专门从事SEO的,几个月来一直都在维护和优化按摩器排行榜www.yziyuan.com这个网站,并从中总结了很多的经验和知识.今天要分享的是<搜索引擎基础知识和工作原理>,这是最基本的概念吧, 第一部分:什么是搜索引擎? 1,定义? 官方定义: 搜索引擎是指根据一定的策略.运用特定的计算机程序从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务,将用户检索相关的信息展示给用户的系统.百度和谷歌等是搜索引擎的代表. 我的理解是: 按照搜索引擎的搜索规则去设置目标网站的

机器学习——svm支持向量机的原理

前言     动笔写这个支持向量机(support vector machine)是费了不少劲和困难的,原因很简单,一者这个东西本身就并不好懂,要深入学习和研究下去需花费不少时间和精力,二者这个东西也不好讲清楚,尽管网上已经有朋友写得不错了(见文末参考链接),但在描述数学公式的时候还是显得不够.得益于同学白石的数学证明,我还是想尝试写一下,希望本文在兼顾通俗易懂的基础上,真真正正能足以成为一篇完整概括和介绍支持向量机的导论性的文章.     本文在写的过程中,参考了不少资料,包括<支持向量机导论

关于搜索引擎的基础知识和工作原理

摘要: 大家好,我是专门从事SEO的,几个月来一直都在维护和优化按摩器排行榜www.yziyuan.com这个网站,并从中总结了很多的经验和知识.今天要分享的是<搜索引擎基础知识和工作原理>,这 大家好,我是专门从事SEO的,几个月来一直都在维护和优化按摩器排行榜www.yziyuan.com这个网站,并从中总结了很多的经验和知识.今天要分享的是<搜索引擎基础知识和工作原理>,这是最基本的概念吧, 第一部分:什么是搜索引擎? 1,定义? 官方定义: 搜索引擎是指根据一定的策略.运用

win7宽带提速方法和上网加速器原理

使用电脑中最让人蛋疼的就是上网速度了,上网速度如果快的话,那么肯定非常爽.而如果上网速度很慢,开网页都很卡.那么给人的感觉就是非常不爽了,那么使用win7要怎么加速上网速度呢?上网加速的原理又是什么? 1 上网加速的原理: TCP/IP默认的数据传输单元接受缓冲区的大小为576字节,要是将这个缓冲区的大小设置得比较大的话,一旦某个TCP/IP分组数据发生错误时,那么整个数据缓冲区中的所有分组内容,都将被丢失并且进行重新传送;显然不断地重新进行传输,会大大影响ADSL传输数据的效率.为此,设置合适