Java Annotation(注解)

 

Annotation

      Java注解是在JDK5时引入的新特性。
      我们可以利用注解帮我们在代码中添加一些其它的信息,如警告错误探测、警告信息提示、引入其它的方法等等。通过注解的方式,可以简化我们的代码,不需要编写很多冗余的代码。
       我们定义了一个日志采集的注解,当我们需要对某个方法的运行时的传入参数、输出数据、异常信息等信息进行记录。我们只需要讲我们的注解放到该方法的上面即可,这样就不用我们在方法中编写日志记录的代码了。这样的代码看起来,清晰明了。也会提高编码效率。

注解


我们如何定义注解,我们需要使用注解给我们提供的“元注解”,来帮助我们定义注解。


元注解


元注解的作用就是负责注解其它注解的。它们被用来提供对其它注解类型进行解释说明。通俗讲,元注解就是帮助我们自定义注解时用到的方法,只不过是这种方法也被定义成了注解的形式。所以我们可以利用元注解来自定义注解。

  • @Target (目标、指标)
  • @Retention (保留、保持)
  • @Documented (文件化、证明、记录在案)
  • @Inherited (继承、继任)

 

@Target


描述注解的使用范围(可以用在什么地方)。注解可以被用到packages、types(类、接口、枚举、注解)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数、本地变量(循环变量、catch参数)。

ElementType:可配置的值

  • CONSTRUCTOR:  表示该注解可以被用到构造器上。
  • FIELD:  表示该注解可以被用到实体类的字段(成员变量、对象、属性等)上。
  • LOCAL_VARIABLE:  表示该注解可以被用到局部变量上。
  • METHOD:  表示该注解可以被用到方法上。
  • PACKAGE:  表示该注解可以被用到包上。
  • PARAMETER:  表示该注解可以被用到参数上。
  • TYPE:  表示该注解可以被用到类(class)、接口(interface)、注解(@interface)、枚举(enum)上。

实例

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableId {
   // 使用范围为字段
}

    上面的 @TableId 例子的使用范围为字段。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {
   // 使用范围为类、接口(包括注解类型) 或enum
}

    上面的 @TableName 例子的使用范围为类(class)、接口(interface)、注解(@interface)、枚举(enum)。

 

@Retention


      描述注解的生命周期(表示在什么级别时保存该注解信息。这里的生命周期是指生命周期中的一段时间范围,在那个时间范围是有效的,这里的时间范围不是时钟的时间,是指程序中的某个期间,如,编译期间、解释期间等)。

  • 某些注解仅出现在源代码中,在编译时被编译器丢弃。
  • 某些注解被编译在class文件中。
  • 编译在class文件中的注解可能会被虚拟机忽略。
  • 某些注解在class被装载时将被读取。

 

RetentionPoicy 可配置的值

 

  • SOURCE: 表示该注释的在源文件(源代码)中是有效的,在编译阶段被丢弃,这些注解在编译结束之后不再有任何意义。它们不会被写入到字节码中。
  • CLASS: 表示该注解在class字节码文件中是有效的。当进行类加载的时候被丢弃(注解的默认使用方式)。
  • RUNTIME: 始终不会被丢弃。运行期间也保留该注解,因此可以使用反射机制读取该注解的信息(自定义注解通常使用这种方式)。

实例

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {
	//在运行时有效
}

    在运行时有效

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
	// 在源文件(代码)中有效。
}

      该注解时lombok的注解,会帮我们的实体类自动生成setter,getter 等方法,这样我们的源代码中就不用写那么多setter,getter等方法了,看着很清晰,但是在编译代码时,会自动帮我们把setter,getter等方法编译出来。

 

@Documented


      描述注解的一个标记状态,表示是否需要将注解信息添加到java文档中。该元注解没有配置参数。需要将注解信息添加到文档中就把这个注解加上即可,反之不用加。

实例

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {
	//需要将该注解信息添加到Java文档中
}

 

@Inherited

       描述注解的一个标记状态,表示某个被标注的类型是被继承的。如果一个注解使用了该配置,这个注解又被用到了一个class上,那么该注解将会被用到该class的子类上,本类不会使用。

实例

@Inherited
public @interface TableName {
	//该注解将被用在使用此注解的class的子类上
}

自定义注解

       通过上面对于注解元注解的介绍,对注解有了一个初步的了解,下面我们通过自定义注解,来加深注解的认识,并去了解在自定义注解时有那些需要注意的地方。

  1. 使用@interface来声明一个注解。 
  2. 在进行自定义注解时,自定义的注解会自动会继承java.lang.annotation.Annotation这个接口,由编译程序自动完成其它细节。
  3. 在自定义注解时,不能再去继承其它类或者接口。
  4. 参数成员只能使用public或者默认(default)这两个访问修饰符。
  5. 参数成员只能用基本数据类型(byte,short,char,int,long,float,double,boolean)和String、Enum、Class、annotation等类型,及这些类型的数组。

 

 

 

你可能感兴趣的:(Java)