注解简单分析

本文详细介绍了Java中的注解,包括定义、作用分类、元注解、内建注解(如@Deprecated、@Override和@SuppressWarnings)以及自定义注解。注解在编译时和运行时的解析方式以及如何使用反射进行注解解析。此外,还探讨了编译时注解的处理,如注解处理器的工作原理和使用AutoService简化注解处理器的注册。
摘要由CSDN通过智能技术生成

注解简单分析

一、定义

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

二、作用分类

  1. 编写文档:通过代码里标识的注解生成文档 (生成文档doc文档)

  2. 代码分析:通过代码里标识的注解对代码进行分析 (使用反射)

  3. 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查 (Override)

三、注解分类

3.1 元注解

元注解是由java API提供的,是专门用来定义注解的注解,常用的元注解主要包括Documented、Inherited、Retention、Target四个,其作用分别如下:

(1) Documented:

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
   
}

表示拥有该注解的元素可通过javadoc此类的工具进行文档化。注解只是一个标记的话,那么使用javadoc生成文档时,这些注解都不会存在于文档中,要使注解在文档中也存在,就可以在使用了注解的作用对象上加上@Documented这个注解。javadoc所生成的文档就会带上注解信息。

(2) Inherited:

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
   
}

该注解表示子类可以集成加载父类上的注解。但要注意:

  1. 注解定义在类上面,子类是可以继承该注解

  2. 注解定义在方法上面,子类也可以继承该注解,但是如果子类复写了父类中定义了注解的方法,那么子类将无法继承该方法的注解,也就是说,子类在复写父类中被@Inherited标注的方法时,会将该方法上面的注解覆盖掉

  3. Interface的实现类(implements实现)无法继承接口中所定义的被@Inherited标注的注解

(3) Retention:

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
   
    RetentionPolicy value();
}

表示该注解类型的注解保留的时长。当注解类型声明中没有@Retention元注解,则默认保留策略为RetentionPolicy.CLASS。关于保留策略(RetentionPolicy)是枚举类型,共定义3种保留策略,如下表:

RetentionPolicy 含义
SOURCE 仅存在Java源文件,经过编译器后便丢弃相应的注解
CLASS 存在Java源文件,以及经编译器后生成的Class字节码文件,但在运行时VM不再保留注释
RUNTIME 存在源文件、编译生成的Class字节码文件,以及保留在运行时VM中,可通过反射性地读取注解

(4) Target:

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
   
    ElementType[] value();
}

表示该注解类型的所使用的程序元素类型。当注解类型声明中没有@Target元注解,则默认为可适用所有的程序元素。如果存在指定的@Target元注解,则编译器强制实施相应的使用限制。关于程序元素(ElementType)是枚举类型,共定义8种程序元素,如下表:

ElementType 含义
ANNOTATION_TYPE 注解类型声明
CONSTRUCTOR 构造方法声明
FIELD 字段声明(包括枚举常量)
LOCAL_VARIABLE 局部变量声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注解类型)或枚举声明

3.2 内建注解

在内建注解中,常用到三种注解类,即常用到的Deprecated、Override和SuppressWarnings.

(1) Deprecated:

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
   
}

用途:用于告知编译器,某一程序元素(比如方法,成员变量)不建议使用时,应该使用这个注解。Java在javadoc中推荐使用该注解,一般应该提供为什么该方法不推荐使用以及相应替代方法。

注解类型分析: @Deprecated可适合用于除注解类型声明之外的所有元素,保留时长为运行时VM。

在使用Eclipse或AS编写程序过程中,有一些方法编写出来之后被画上了中划线,表示该方法已过时,建议使用新的一些方法代替。如:viewPager.setOnPageChangeListener()方法在安卓API23中已过时,在上面被画上了中划线,在源代码中的该方法上赫然多了一个注解@Deprecated,可使用addOnPageChangeListener()方法代替。如果使用javac命令编译,会弹出:”注意:使用或覆盖了已过时的API“。

(2) Override:

源码:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
   
}

用途:用于告知编译器,我们需要覆写父类的当前方法。这是开发过程中最常遇到的注解了,表示复写父类中的方法。如果方法上有这条注解但没有重写父类方法,则会生成一条错误消息。这个注解有效地保证了方法一定会被复写。比如开发过程中,手动在子类中复写父类方法,只正确写出了方法名称,未写正确方法的参数,则相当于方法的重载,并不是复写。这种问题如果在功能上有错误产生,在检查过程中是很难找到的。使用@Override注解,有效地表明,此方法是复写父类的方法,不会产生手动的错误问题。

注解类型分析:@Override可适用元素为方法,仅仅保留在java源文件中。

(3) SuppressWarnings:

源码:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
   
    String[] value();
}

用于ÿ

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值