Annotation(注解)

Posted xxMYxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Annotation(注解)相关的知识,希望对你有一定的参考价值。

14 Annotation(注解)

JDK 5 开始,java增加了对元数据(METAData)的支持,也就是Annotation(其实是代码里的特殊标记),这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过注解程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息

Annotation 提供了一种为程序元素设置的元数据的方法。指定指出的是,Annotation就像修饰符一样 可以用来修饰 包 类 构造器 方法 成员变量 参数 局部变量

Annotation 是一个接口,程序可以通过反射来获取指定程序元素的Annotation对象 然后通过Annotation对象来获取注解里的元数据。

 

14.1 基本Annotation

Annotation必须使用工具来处理,工具负责提取Annotation里包含的元数据,工具还会根据这些元数据增加额外的功能,

使用Annotation时需要在前面增加@,并把该Annotation当成修饰符使用,用于修饰它支持的程序元素

5个基本的Annotation如下

1. @Override

2. @Deprecated

3. @Suppress Warnings

4. @Safa Varargs

5. @FunctionlInterface

 

14.1.1 限定重写父类方法@Overrid

@Override就是用来指定方法覆盖的,它可以强制一个子类必须覆盖父类的方法(主要作用是用来保证子类的方法名不被写错,只能修饰方法)

 

14.1.2 标记已经过时 @Deprecated

@Deprecated用于表示某一个程序元素(类、方法)记过时,当程序使用已经过时的类、方法时将会给出警告

14.1.3 抑制编译器警告@Suppress Warnings

@Suppress Warnings指示被该Annotation修饰的程序元素(以及该程序元素中所有子类元素)取消显示执行的编译器警告@Suppress Warnings会一直作用于该程序元素的所有子元素

14.1.4 java 7 的堆污染警告与@Safa Varargs

把一个不带泛型的对象赋值给一个带泛型的对象,往往会引发这种 堆污染

java 7 开始,java编译器将会进行更严格的检查,在定义方法时就发出堆污染警告,这样保证更早的注意到漏洞

但有些时候也不需要看到这个警告 则可以通过如下三个方法啦抑制这些警告

1. 使用@Safa Varargs

2. 使用@Suppress Warnings“unchecked”)修饰

3. 编译时使用-Xlint:varargs选项

 

14.1.5 java 8 的函数式接口与@FunctionlInterface

如果接口中只有一个抽象方法(可以包含多个默认方法或多个static方法),该接口就是函数式接口 @FunctionlInterface就是用来指定某一个接口必须是函数式接口

 

14.2 JDK的元Annotation

jdk处理在java.lang下提供了5个基本的Annotation之外,还在java.lang.annotion包下提供了6Meta Annotation (Annotation) 其中5个元Annotation用于修饰Annotation定义,其中@Repeatable 专门用于定义java 8 新增的重复注解

14.2.1 使用@Retention

@Retention只能用于修饰Annotation定义,用于指定被修饰的Annotation可以保留多长时间@Retention包含一个RetentionPolicy 类型的value 变量,所以使用@Retention时必须为该value成员变量指定值

value成元变量有3个值

1. RetentionPolicy.CLASS 编译器将Annotation记录在class文件中,当运行java程序时,JVM不可以获取Annotation信息(默认值)

2. RetentionPolicy.RUNTIME 编译器将Annotation记录在class文件中,当运行java程序时,JVM可以获取Annotation信息,程序可以通过反射湖区该Annotation信息

3.RetentionPolicy.SOURCE Annotation只保存在源代码中,编译器直接丢弃这种Annotation

 

14.2.2 使用@Target

@Target也只能修饰一个Annotation定义,它用于指定被修饰的Annotation能用于修饰哪些程序单元@Target 也包含一个名为value的成员变量

1. ElementType.ANNOTATION_TYPE 指定该策略的Annotation只能修饰Annotation

2. ElementType.CONSTRUCTOR指定该策略的Annotation只能修饰构造器

3. ElementType.FIELD 指定该策略只能修饰成员变量

4. ElementType.LOCAL_VARIABLE 指定该策略只能修饰局部变量

5. ElementType.METHOD 指定该策略只能修饰方法

6. ElementType.PACKAGE 指定该策略只能修饰包

7. ElementType.PARAMETER 指定该策略只能修饰参数

8. ElementType.TYPE 指定该策略只能修饰参数

 

14.2.3 使用@Documented

@Documented用于指定该元Annotation修饰的Annotation类被javadoc工具读成文档,表明白API中会包含Annotation的说明

 

14.2.4 使用@Inherited

@InheritedAnnotation指定被它修饰的Annotation将具有继承性--如果一个类使用了@XXX注解 子类将自动继承@XXX修饰

 

14.3 自定义Annotation

14.3.1 定义Annotation

定义新的Annotation类型使用@interface关键字,定义一个新的Annotation类型与定义一个接口非常像

 

定义了该Annotation之后,就可以在程序的任何地方使用该Annotation 使用Annotation的语法非常类似于 public final 这样的修饰符

也可以定义Annotation的成员变量为其制定初始值(默认值)制定成员变量的默认值可以使用default关键字 如果使用中指定了值则默认值就不会起作用

 

根据Annotation是否可以包含成员变量,可以把Annotation分为两类

1.标记 没有定义成员变量的Annotation类型被称为标记

2.元数据 定义了成员变量的Annotation类型被称为 元数据

 

14.3.2 提前Annotation信息

使用了Annotation修饰类 方法成员变量等成员后,这些Annotation并不会自己生效,必须由开发者提供相应的工具来提取并处理Annotation信息

java使用Annotation接口来代表程序元素前面的注解,该接口是所有注解的父接口java 5 java.lang.reflect包下新增了AnnotationElement接口,该接口代码程序中可以接收注解的程序元素

该接口下主要有如下几个实现类 Class Construtor Field Method Package

 

java 1.5 java.lang.reflect包提供了反射API增加了读取运行时Annotation的能力(只有定义Annotation时使用@Retention.RUNTIME时)该Annotation才会在运行时可见,JVM才会在加载*.class文件时读取保存在class文件中 Annotation

AnnotationElement对象是所有元素的(Class Construtor Field Method Package )的父接口所有程序通过反射获取了某个类的AnnotationElement对象,之后,程序就可以调用该对象的如下几个方法来访问Annotation元素

 

14.3.4 java 8 新增的重复注解

java 8 之前 同一个程序元素前最多只能使用一个相同类型的Annotation;如果需要在同一个元素前使用多个相同类型的Annotation,则必须使用Annotation“容器”,有时需要在Action类中使用多个@Result注解

开发重复注解需要使用@Repeatable修饰

 

14.3.5 java 8 新增的 Type Annotation

java 8 ElementType枚举增加了Tpye_PARAMETERTYPE_USE 两个枚举值,这样就允许定义枚举时,都是使用@TargetElement.TYPE_USE)这种注解被称为类型注解

 

java 8 开始可以在使用到类型的地方使用注解

1.创建对象(new关键字)

2.类型转换

3.使用implement实现接口

4.使用throws什么抛出异常

但是java 并没有提供对Type Annotation执行检查的框架,所有需要开发者自己实现Type Annotation的检查框架

 

14.4 编译时处理Annotation

APT(Annotation Processing Tool)是一种注解处理工具,它对源代码进行检测,并找出源代码所包含的Annotation信息,然后针对Annotation信息进行额外的处理

使用APT 工具处理Annotation时,可以根据源文件中的Annotation生成额外的源文件和其他的文件,APT还会编译生成的源代码文件和原来的源文件,将他们一起生成class文件

 

API 可在编译源文件是同时可以生成附属文件 这些附属文件也都和源代码相关,使用APT可以代替传统的对代码信息和属性文件的维护工作

 

每个Annotation处理器都需要实现javax.annotaton.processing 包下的Processor接口也可以通继承 AbstractProcessor的方式实现Annotation处理器,一个处理器可以处理一种或者多种Annotation类型

 

与前面的Annotation通过反射来获取信息不同 此处的Annotation处理器是通过RoundEnvironment 里包含 一个getElementAnnotationWith()

以上是关于Annotation(注解)的主要内容,如果未能解决你的问题,请参考以下文章

[1] 注解(Annotation)-- 深入理解Java:注解(Annotation)基本概念

JAVA注解Annotation

[3] 注解(Annotation)-- 深入理解Java:注解(Annotation)--注解处理器

一起来学Java注解(Annotation)

Java注解Annotation

深入理解Java:注解(Annotation)自己定义注解入门