注解

作者: seraphlee | 来源:发表于2017-09-19 14:39 被阅读9次

注解知识点

Java代码中使用注释是为了提升代码的可读性,也就是说,注释是给人看的(对于编译器来说没有意义)。注解可以看做是注释的“强力升级版",它可以向编译器、虚拟机等解释说明一些事情(也就是说它对编译器等工具也是“可读”的)。比如@Override注解,它的作用是告诉编译器它所注解的方法是重写的父类中的方法,这样编译器就会去检查父类是否存在这个方法,以及这个方法的签名与父类是否相同。

也就是说,注解是描述Java代码的代码,它能够被编译器解析,注解处理工具在运行时也能够解析注解。除了向编译器等传递一些信息,我们也可以使用注解生成代码。比如我们可以使用注解来描述我们的意图,然后让注解解析工具来解析注解,以此来生成一些”模板化“的代码。比如Hibernate、Spring等框架大量使用了注解,来避免一些重复的工作。注解是一种”被动“的信息,必须由编译器或虚拟机来“主动”解析它,它才能发挥自己的作用

元注解

元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明

1. @Target

@Target说明了Annotation所修饰的对象范围,取值(ElementType)有:

CONSTRUCTOR:用于描述构造器
FIELD:用于描述域
LOCAL_VARIABLE:用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Target({ElementType.FIELD, ElementType.METHOD})

2. @Retention
@Retention定义了该Annotation的“生命周期”,取值(RetentionPoicy)有:
SOURCE:在源文件中有效(即源文件保留)
CLASS:在class文件中有效(即class保留)
RUNTIME:在运行时有效(即运行时保留)

@Retention(RetentionPolicy.RUNTIME)

3. @Documented
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化
Documented是一个标记注解,没有成员

4. @Inherited
@Inherited元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类

自定义注解

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

定义注解格式:
  public @interface 注解名 {定义体}

注解参数的可支持数据类型:

1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface SerializedName {
  String value();
  String[] alternate() default {};
}

注解处理器

1.运行时注解处理器
java.lang.reflect包中的所有API都支持读取运行时Annotation的能力,即属性为@Retention(RetentionPolicy.RUNTIME)的注解。

//获取所有属性  
Field[] fields = clazz.getDeclaredFields();  

for(Field field : fields){  
//根据注解的类型做不同的处理  
if(field.isAnnotationPresent(XXX.class)){  
    //获取该类型的注解  
    XXX xx = field.getAnnotation(XXX.class);  
    //获取注解中元素值  
    xxx.方法名;  
}else if(field.isAnnotationPresent(FruitColor.class)){ 
    something
}

2.编译时注解处理器
采用APT(Annotation Processor Tool)
编译时注解处理器编译一个注解时,主要分2步

  • 继承AbstractProcessor,实现自己的注解处理器
  • 注册处理器,并打包成jar

4个重要方法,其中process是必须实现的抽象方法
init(ProcessingEnvironment processingEnv) 该方法由注解处理器自动调用,其中ProcessingEnvironment类提供了很多有用的工具类:Filter,Types,Elements,Messager等

getSupportedAnnotationTypes() 该方法返回字符串的集合表示该处理器用于处理那些注解

getSupportedSourceVersion() 该方法用来指定支持的Java版本,一般来说我们都是支持到最新版本,因此直接返回SourceVersion.latestSupported()即可

process(Set annotations, RoundEnvironment roundEnv) 该方法是注解处理器处理注解的主要地方,我们需要在这里写扫描和处理注解的代码,以及最终生成的java文件。其中需要深入的是RoundEnvironment类,该用于查找出程序元素上使用的注解

相关文章

  • 注解学习笔记

    什么是注解注解分类注解作用分类 元注解 Java内置注解 自定义注解自定义注解实现及使用编译时注解注解处理器注解处...

  • 注解与反射

    注解 声明一个注解类型 元注解 在定义注解时,注解类也能够使用其他的注解声明。对注解类型进行注解的注解类,我们称之...

  • 1.8 Java 注解annotation

    1.1 注解声明 Java注解Annotation,有声明注解和元注解 元注解:Java提供的元注解,所谓元注解就...

  • 注解的使用

    元注解 注解 注解本质就是接口: 元注解:修饰注解的注解 自定义注解 Text.java FruitName.ja...

  • 注解

    Java注解 注解 元注解 自定义注解 元注解:负责注解其他注解 共有4个标准的meta-annotation类型...

  • Spring高级应用之组合注解和元注解

    1.核心概念: 元注解:可以注解在其他注解上的注解;被注解的注解成为组合注解; 2.组合注解的定义步骤 定义组合注...

  • 2016.10.13-关于注解的自定义和注解的解析

    注解可以分为:1、标识性注解(没有成员变量) 2、注解 3、元注解(注解的注解) 1、注解的自定义 自定义注解的格...

  • 自定义注解

    注解分类 1、代码注解2、编译时注解3、运行时注解 注解范例 使用注解的类 注解解析类 注解实战 需求1、有一张用...

  • 【JAVA】注解

    元注解 用来定义、声明注解的注解。 @Inherited注解 使用此注解声明出来的自定义注解,在使用此自定义注解时...

  • Spring Boot常用注解

    注解速览 配置加载相关 Bean 声明注解 Bean 注入注解 SpringMVC 注解 MyBatis 注解 配...

网友评论

      本文标题:注解

      本文链接:https://www.haomeiwen.com/subject/rpiwsxtx.html