原文地址

注解的本质

「java.lang.annotation.Annotation」接口中有这么一句话,用来描述『注解』。

The common interface extended by all annotation types

所有的注解类型都继承自这个普通的接口(Annotation)

这句话有点抽象,但却说出了注解的本质。我们看一个 JDK 内置注解的定义:

  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.SOURCE)
  3. public @interface Override {
  4. }

这是注解 @Override 的定义,其实它本质上就是:

  1. public interface Override extends Annotation{
  2. }

没错,注解的本质就是一个继承了 Annotation 接口的接口。有关这一点,你可以去反编译任意一个注解类,你会得到结果的。

一个注解准确意义上来说,只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。

解析一个类或者方法的注解往往有两种形式,一种是编译期直接的扫描,一种是运行期反射。

元注解

『元注解』是用于修饰注解的注解,通常用在注解的定义上。

JAVA 中有以下几个『元注解』:

  • @Target:注解的作用目标
  • @Retention:注解的生命周期
  • @Documented:注解是否应当被包含在 JavaDoc 文档中
  • @Inherited:是否允许子类继承该注解

@Target

@Target 注解指明该注解可以作用哪些对象上。

  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target(ElementType.ANNOTATION_TYPE)
  4. public @interface Target {
  5. /**
  6. * Returns an array of the kinds of elements an annotation type
  7. * can be applied to.
  8. * @return an array of the kinds of elements an annotation type
  9. * can be applied to
  10. */
  11. ElementType[] value();
  12. }

注解接收一个ElementType数组,ElementType是一个枚举,成员如下:

  • ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
  • ElementType.FIELD:允许作用在属性字段上
  • ElementType.METHOD:允许作用在方法上
  • ElementType.PARAMETER:允许作用在方法参数上
  • ElementType.CONSTRUCTOR:允许作用在构造器上
  • ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
  • ElementType.ANNOTATION_TYPE:允许作用在注解上
  • ElementType.PACKAGE:允许作用在包上
  • ElementType.TYPE_PARAMETER:允许作用在类型参数上
  • ElementType.TYPE_USE:允许作用在类型上

@Retention

@Retention 用于指明当前注解的生命周期

  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target(ElementType.ANNOTATION_TYPE)
  4. public @interface Retention {
  5. /**
  6. * Returns the retention policy.
  7. * @return the retention policy
  8. */
  9. RetentionPolicy value();
  10. }

注解接收一个RetentionPolicy数据,RetentionPolicy是个枚举,成员如下:

  • RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
  • RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
  • RetentionPolicy.RUNTIME:永久保存,可以反射获取

JAVA 的内置三大注解

  • @Override
  • @Deprecated 标识类或方法不再推荐使用
  • @SuppressWarnings 主要用来压制 java 的警告

实现一个自己的注解

定义一个注解:

  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface HelloAnnotation {
  4. String value() default "Hello annotation!";
  5. }

使用这个注解:

  1. public class UseAnnotation {
  2. @HelloAnnotation
  3. public void hello() {
  4. System.out.println("hello");
  5. }
  6. @HelloAnnotation("Hello world!")
  7. public void helloWorld() {
  8. System.out.println("Hello world!");
  9. }
  10. }

注解最重要的部分在于对注解的处理。注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行特定的处理。如果没有注解处理器,注解就是个注释,或者连注释都不如。

处理这个注解:

  1. public class Test {
  2. public static void main(String[] args) {
  3. testAnnotation(UseAnnotation.class);
  4. }
  5. private static void testAnnotation(Class<?> cl) {
  6. for (Method m : cl.getDeclaredMethods()) {
  7. HelloAnnotation ha = m.getAnnotation(HelloAnnotation.class);
  8. if (ha != null) {
  9. System.out.println("Found My Annotation: " + ha.value());
  10. }
  11. }
  12. }
  13. }

输出结果:

  1. Found My Annotation: Hello annotation!
  2. Found My Annotation: Hello world!

参考资料

JAVA 注解的基本原理

Java注解基本原理

原文首发在我的简书 [https://www.jianshu.com/p/c342606e255d](https://www.jianshu.com/p/c342606e255d

Java 注解基本原理的更多相关文章

  1. Java注解基本原理

    注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁. 注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致.Java S ...

  2. java 注解 基本原理 编程实现

    摘要: java 1.5开始引入了注解和反射,正确的来说注解是反射的一部分,没有反射,注解无法正常使用,但离开注解,反射依旧可以使用,因此来说,反射的定义应该包含注解才合理一些. java 1.5开始 ...

  3. 10分钟学会JAVA注解(annotation)

    (原) 先认识注解(Annotation) 定义类用class,定义接口用interface,定义注解用@interface 如public @interface AnnotationTest{} 所 ...

  4. Java注解

    Java注解其实是代码里的特殊标记,使用其他工具可以对其进行处理.注解是一种元数据,起到了描述.配置的作用,生成文档,所有的注解都隐式地扩展自java.lang.annotation.Annotati ...

  5. 19.Java 注解

    19.Java注解 1.Java内置注解----注解代码 @Deprecated                                    //不推荐使用的过时方法 @Deprecated ...

  6. Java注解入门

    注解的分类   按运行机制分:   源码注解:只在源码中存在,编译后不存在 编译时注解:源码和编译后的class文件都存在(如@Override,@Deprecated,@SuppressWarnin ...

  7. java注解(Annotation)解析

    注解(Annotation)在java中应用非常广泛.它既能帮助我们在编码中减少错误,(比如最常见的Override注解),还可以帮助我们减少各种xml文件的配置,比如定义AOP切面用@AspectJ ...

  8. JAVA 注解的几大作用及使用方法详解

    JAVA 注解的几大作用及使用方法详解 (2013-01-22 15:13:04) 转载▼ 标签: java 注解 杂谈 分类: Java java 注解,从名字上看是注释,解释.但功能却不仅仅是注释 ...

  9. attilax.java 注解的本质and 使用最佳实践(3)O7

    attilax.java 注解的本质and 使用最佳实践(3)O7 1. 定义pojo 1 2. 建立注解By eclipse tps 1 3. 注解参数的可支持数据类型: 2 4. 注解处理器 2 ...

随机推荐

  1. 学习:简单使用MFC创建对话框窗口

    MFC介绍:微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows ...

  2. SparkStreaming消费kafka中数据的方式

    有两种:Direct直连方式.Receiver方式 1.Receiver方式: 使用kafka高层次的consumer API来实现,receiver从kafka中获取的数据都保存在spark exc ...

  3. python操作excel获取内容

    背景:从excel表中获取请求url.请求数据.请求类型.预期结果 因此,需要学会如何使用python从excel获取这些信息 #coding=utf-8 import xlrd #创建对象时,获取对 ...

  4. JavaScript == 与 === 区别

    1.对于 string.number 等基础类型,== 和 === 是有区别的 a)不同类型间比较,== 之比较 "转化成同一类型后的值" 看 "值" 是否相等 ...

  5. [PHP]全国省市区信息,mysql数据库记录

    下载地址: https://files.cnblogs.com/files/wukong1688/T_Area.zip 或者也可以复制如下内容: CREATE TABLE IF NOT EXISTS ...

  6. 【搜索】$P1092$虫食算

    题目链接 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同 ...

  7. 牛客网 牛客练习赛4 A.Laptop-二维偏序+离散化+树状数组

    A.Laptop 链接:https://ac.nowcoder.com/acm/contest/16/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其 ...

  8. planAhead的启动时间较长

    发现Xilinx planAhead的启动时间约需10秒钟.

  9. 分布式id的生成方式——雪花算法

    雪花算法是twitter开源的一个算法. 由64位0或1组成,其中41位是时间戳,10位工作机器id,12位序列号,该类通过方法nextID()实现id的生成,用Long数据类型去存储. 我们使用id ...

  10. linux jar/war包 后台运行

    1. 基础版,当前ssh窗口锁定,按CTRL+C打断程序运行:或关闭窗口,程序退出 java -jar flowable-modeler.war 2. 改进版,当前ssh窗口不锁定,窗口关闭时,程序终 ...