java注解讲解

一、注解
Annotation
  Annotation其实是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用Annotation,程序开发人员可以在不改变原有逻辑的情况下,在源文件嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。

  Annotation提供了一条为程序元素设置元数据的方法,从某些方面来看,Annotation就像修饰符一样被使用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明,这些信息被存储在Annotation的“name=value”对中。

  Annotation能被用来为程序元素(类、方法、成员变量等)设置元数据。值得指出的是:Annotation不能影响程序代码的执行,无论增加、删除Annotation,代码都始终如一地执行。如果希望让程序中的Annotation能在运行时起一定的作用,只有通过某种配套的工具对Annotation中的信息进行访问的处理,访问和处理Annotation的工具统称APT(Annotation Processing Tool)。
基本的Annotation:
  Annotation必须使用工具来处理,工具负责提取Annotation里包含的元数据,工具还会根据这些元数据增加额外的功能。在系统学习新的Annotation语法之前,先看一下Java提供的三个基本Annotation的用法:使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用,用于修饰它支持的程序元素。

三个基本的Annotation如下:

       @Override 限定重写父类的方法
       @Deprecated 标示已过时
       @SuppressWarnings 抑制编译器警告

二、 自定义Annotation
       定义新的Annotation类型使用@interface关键字,它用于定义新的Annotation类型。定义一个新的Annotation类型与定义一个接口非常像,如下代码可定义一个简单的Annotation:

public @interface Login {

}

定义了该Annotation之后,就可以在程序任何地方来使用该Annotation,使用Annotation时的语法非常类似于public、final这样的修饰符。通常可用于修饰程序中的类、方法、变量、接口等定义,通常我们会把Annotation放在所有修饰符之前,而且由于使用Annotation时可能还需要为其成员变量指定值,因而Annotation长度可能比较长,所以通常把Annotation另放一行,如下程序所示:

/**
 * 定义一个Annotation
 */
public @interface Login {

}

class LoginTest{
    /**
     * 使用Annotation
     */
    @Login
   public void login(){

    }
}

Annotation不仅可以是这种简单Annotation,Annotation还可以带成员变量,Annotation的成员变量在Annotation定义中以无参数方法的形式声明。其方法名和返回值定义了该成员的名字和类型。如下代码可以定义一个有成员变量的Annotation:

/**
 * 定义一个注解
 */
public @interface Login {
    //定义两个成员变量
    String username();
    String password();
}

一旦在Annotation里定义了成员变量之后,使用该Annotation时应该为该Annotation的成员变量指定值,如下代码所示:

/**
 * 定义一个注解
 */
public @interface Login {
    //定义两个成员变量
    String username();
    String password();
}

class LoginTest{
    /**
     * 使用注解
     */
    @Login(username="lisi", password="111111")
    public void login(){

    }
}

我们还可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可使用default关键字,如下代码:

/**
 * 定义一个注解
 */
public @interface Login {
    //定义两个成员变量
    //以default为两个成员变量指定初始值
    String username() default "zhangsan";
    String password() default "123456";
}

 如果为Annotation的成员变量指定了默认值,使用该Annotation则可以不为这些成员变量指定值,而是直接使用默认值。如下代码:
 

/**
 * 定义一个注解
 */
public @interface Login {
    //定义两个成员变量
    //以default为两个成员变量指定初始值
    String username() default "zhangsan";
    String password() default "123456";
}

class LoginTest{
    /**
     * 使用注解
   * 因为它的成员变量有默认值,所以可以无须为成员变量指定值,而直接使用默认值
     */
    @Login
    public void login(){

    }
}

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

value成员变量的值只能是如下三个:

RetentionPolicy.CLASS: 编译器将把注释记录在class文件中。当运行Java程序时,JVM不在保留注释,这是默认值。
RetentionPolicy.RUNTIME:编译器将把注释记录在class文件中。当运行Java程序时,JVM也会保留注释,程序可以通过反射获取该注释。
RetentionPolicy.SOURCE: 注解仅存在于源码中,在class字节码文件中不包含。

使用@Target
  @Target也是用于修饰一个Annotation定义,它用于指定被修饰Annotation能用于修饰那些程序元素。@Target Annotation也包含一个名为value的成员变量,该成员变量只能是如下几个:

ElementType.ANNOTATION_TYPE: 指定该策略的Annotation只能修饰Annotation。
ElementType.CONSTRUCTOR: 指定该策略的Annotation能修饰构造器。
ElementType.FIELD: 指定该策略的Annotation只能修饰成员变量。
ElementType.LOCAL_VARIABLE: 指定该策略的Annotation只能修饰局部变量。
ElementType.METHOD: 指定该策略的Annotation只能修饰方法。
ElementType.PACKAGE: 指定该策略的Annotation只能修饰包定义。
ElementType.PARAMETER: 指定该策略的Annotation可以修饰参数。
ElementType.TYPE: 指定该策略的Annotation可以修饰类、接口(包括注释类型)或枚举定义。

使用@Documented
  @Documented用于指定该元Annotation修饰的Annotation类将被javadoc工具提取成文档,如果定义Annotation类时使用了@Documented修饰,则所有使用该Annotation修饰的程序元素的API文档中将会包含该Annotation说明。
  
使用@Inherited
  @Inherited 元 Annotation指定被它修饰的Annotation将具有继承性:如果某个类使用了A Annotation(定义该Annotation时使用了@Inherited修饰)修饰,则其子类将自动具有A注释。
参考文档:https://www.cnblogs.com/be-forward-to-help-others/p/6846821.html

猜你喜欢

转载自blog.csdn.net/xzpdskll/article/details/82379784