Java 初识注解

一、注解的基本概念

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

Annotation(注解,也叫元数据)是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符,即描述数据的数据。

Java自带有四种内置注解 (定义在java.lang中):

注解名称 作用
@Override 表示当前方法将覆盖父类中的方法,主要用于保证方法签名和拼写的准确性。
@Deprecated 表示已被废弃,如果使用了被它注解的元素,会被警告。
@SuppressWarnings 关闭编译器的警告信息
@SafeVarargs 表示该方法参数长度可变

Java还提供了四种元注解(定义在java.lang.annotation),用于新注解的创建:

注解名称 作用和可能的参数
@Documented 表示注解将被保存在Javadoc中,无参数
@Retention 表示在什么级别保存注解信息(注解的生命周期),可能的RetentionPolicy参数:
SOURCE:只保存在源代码中,编译时将被编译器丢弃(例如@Override@SuppressWarnings
CLASS:默认项,会被保存在class文件中,但运行时会被虚拟机丢弃
RUNTIME:会被保存在class文件中,运行时被虚拟机保留,并通过反射机制读取信息(例如@Deprecated@SafeVarargs
@Target 表示注解可用于什么地方,可能的ElementType参数:
TYPE:类、接口(包括注解)、enum
FIELD:域声明(包括enum实例)
METHOD:方法声明
PARAMETER:参数声明
CONSTRUCTOR:构造器声明
LOCAL_VARIABLE:局部变量声明
ANNOTATION_TYPE:注解声明
PACKAGE:包声明
@Inherited 允许子类继承父类中的注解,无参数

更多的注解体现在第三方库(如ButterKnife、Retrofit)和Android(如@Nullable)中。

二、详解元注解

@Documented

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

表示注解将被保存在Javadoc中

什么是Javadoc?javadoc是Sun公司提供的一个技术,它可以从源代码中抽取类、方法、成员等注释形成一个和源代码配套的API帮助文档。

举个栗子:
先自定义一个注解,并用@Documented修饰:

@Documented
@interface DocumentedAnnotation {
    String name() default "name";
    int age() default 0;
}

再创建一个类,并在类和方法前加上自定义的注解:

@DocumentedAnnotation(name = "Rimson", age = 18)
public class DocumentedAnnotationTest {

    @DocumentedAnnotation(name = "Rimson", age = 18)
    public String toString() {
        return "hello";
    }
}

接着生成Javadoc文件,笔者使用的是IDEA编译器(也可以直接使用javadoc命令生成),选择菜单栏-> Tools -> Genetate JavaDoc...,选中Whole project并指定Output directory,然后选择OK,不管是这种方式还是javadoc命令行,都能看到以下内容:


在刚才选择的目录中,找到index.html并打开,可以看到类和方法都显示在这个javadoc文件中:


如果去掉自定义注解中的@Documented,再生成javadoc:

自定义注释将不会出现在javadoc中。同理,即使在代码中的toString()方法加上@Override注解,javadoc中也不会出现该注解,因为@Override这个注解本身并没有被加上@Documented

@Retention

用来表示注解的保留策略(声明周期)

  • SOURCE:源码级别,注解只保留在源文件阶段,当.java文件被编译成.class文件时,注解就会被去掉。这种声明周期的注解,常常用于检验代码规范,提示代码错误等等,被编译之后它们就不再起作用。例如@Override@SuppressWarnings只是在编写源代码时,帮助编程人员检验方法签名是否准确以及去除不必要的警告。

  • CLASS:字节码级别,注解保留到字节码文件阶段,当JVM通过ClassLoader向内存中加载字节码文件时,注解就会被去掉;这种生命周期主要运用在,某些需要对字节码进行处理的场合。

  • RUNTIME:运行时级别,上面两种保留策略在运行时都会被去掉,也就是不能通过反射机制,调用getAnnotationgetAnnotations 获取注解的内容;只有这种策略的注解,当JVM运行时,可以获取内容并得到执行。主要用于注解信息非常重要的场合,例如Butterknife的注解。

@Target

表示可以被注解修饰的内容。

@Inherited

加上此注解后的注解,可以被子注解继承。

推荐阅读更多精彩内容

  • 2017.12.16宝清熹微复盘【小确幸】 ①买到嫂子爱吃的枣糕②享受一下打车去哥哥家③我们一起去吃日本料理火锅,...
    熹微林阅读 12评论 0 0
  • 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非...
    萧何爱英语阅读 338评论 0 0
  • 简爱最终还是和罗切斯特先生在一起了。简爱一直追求平等,可是这个时候的简(年轻有活力的,上流社会的女子)和罗切斯特(...
    樱桃裙_72阅读 265评论 0 1