Java学习之注解Annotation

一、 什么是注解(Annotation)?

 1. 概念:

  Annotation是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。通过使用注释,程序开发人员可以可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。

    2. 作用:

  1)不是程序本身,可以对程序做出解释

  2)可以被其他程序读取

     3. 格式

       注解是以“@注释名”在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked");

     4. Annotation在哪里使用?

       可用于包、类、构造器、方法、成员变量、参数、局部变量的声明,相当于给它们添加额外的信息,我们可以通过反射机制编程实现对元数据的访问

二、基本Annotation,5个基本Annotation都在java.lang包下

  1) @Override :此注释只适用于修饰方法,表示一个方法声明打算重写超类中另一个方法的声明;

  2) @Deprecated: 用于表示某个程序元素(类、方法等)已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告。表示不鼓励程序员使用给类、方法。

  3) @SuppressWarnings:指示被该Annotation修饰的程序元素(要以及该程序元素的所有子元素)取消显示指定的编译器警告。抑制编译时的警告信息。与前两个注释有所不同,需要添加一个参数才能正确使用,这些参数已经定义好了,我们选择就可以,参数如下:

        

  4) @SafeVarargs:Java7中的“堆污染”,修饰引发给警告的方法或构造器,类抑制“堆污染”警告;

    堆污染:当把一个不带泛型的对象赋给一个带泛型的得变量时,往往会发生这种“堆污染”

       5) @FunctionallInterface:Java8中规定,如果接口中只有一个抽象方法,该接口就是函数式接口。@FunctionallInterface就是用来指定某个接口必须是函数式接口。

三、自定义Annotation

  1. @interface用来声明一个注解 

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

   2. 其中每一个方法实际上是声明了一个配置参数

           1)方法名称就是参数名称

           2)返回值类型就是参数的类型(返回值类型只能是基本类型、String、Class、enum)

      3)可以通过default来声明参数的默认值(默认值为-1时,表示该参数不存在)

   4)如果只有一个参数成员,一般参数名为value   

@Retention(value=RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
    String name() default " ";
    int age() default 0;
    int id() default -1; //不存在
}

         3. JDK的元注解:用于修饰其他的Annotation定义。作用:负责注解其他注解

   1)@Retention:用于指定被修饰的Annotation可以保留多长时间,@Retention包含了一个RetentionPolicy类型的value参数配置,所以使用@Retention时必须为该value参数指定值;

    

    ---@Retention(RetentionPolicy.SOURCE):将被编译器直接丢弃

   2)@Target:用于指定被修饰的Annotation能用于修饰哪些程序单元,也就是注解的适用范围;@Target包含了一个ElementType类型的value参数配置,所以使用@Target时必须为该value参数指定值;

    

    ---@Target(ElementType.FIELD):只能修饰成员变量

   3)@Documented:用于指定被该元Annotation修饰的Annotation类将被javadoc工具提取成文档,如果定义Annotation类时使用了@Documentedx修饰,则所有使用该Annotation修饰的程序元素的API文档中将会包含该Annotation说明;

   4)@Inherited:指定被它修饰的Annotation将具有继承性---如果某个类使用了@Xxx注解(定义该注解时使用了@Inherited修饰)修饰,则其子类将自动被@Xxx修饰。

  4. 使用反射读取注解的信息:使用注解完成类和表结构的映射关系

    

   1)表名的注解    

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTable {
    String value();
}

   2)属性的注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyField {
    String columnName();
    String type();
    int length();
}

   3)使用反射读取注解

 1 public class Demo03 {
 2     public static void main(String[] args) {
 3         try {
 4                 Class clzz = Class.forName("com.java.annotation.MyStudent");
 5                 //获取该类所有的注解
 6                 Annotation[] annotations = clzz.getAnnotations();
 7                 for(Annotation a :annotations) {
 8                     System.out.println(a);
 9                 }
10                 //获取该类指定的注解
11                 MyTable mb = (MyTable) clzz.getAnnotation(MyTable.class);
12                 System.out.println(mb.value());
13                 
14                 //获取类的属性的注解
15                 Field f = clzz.getDeclaredField("id");
16                 MyField myfield = f.getAnnotation(MyField.class);
17                 System.out.println(myfield.columnName()+"---"+myfield.type()+"---"+myfield.length());
18                 
19             } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 }
原文地址:https://www.cnblogs.com/guodong-wang/p/6980262.html