annotation的概述:

从Java核心内容到JavaEE,一路都可以使用注解方式完成
Annotation是JDK5.0以后提供对元数据的支持,可以在编译、加载和运行时被读取,并执行相应的处理。所谓Annotation就是提供了一种为程序元素设置元数据的方法,可用于修饰包、类、构造器、方法、成员变量、参数和局部变量的声明,这些信息被存储在Annotation的“name=value”对中。

Annotation能被用来为程序元素(类、方法、成员变量等)设置元数据,比如一段代码的作者或者告诉编译器禁止一些特殊的错误,不会影响代码的执行。
作用:主要就是用来替代xml的配置文件.
存在的位置:在对应的Java类中.
使用的范围:用于修饰包,类,构造器,方法,成员变量,参数和局部变量的声明.
存储形式:key\value形式.
注意:不影响原本的代码执行.

注解与XML的区别:
注解: 
优点:直观,简单.配置方式容易.
缺点:配置信息相对过于零散.修改过于麻烦(重新编译)
XML:
优点:与Java类逻辑的关系低耦合.复用性.修改很简单(不用编译)
缺点:编写过于复杂.解析操作过于复杂.

基本用法:

Annotation必须使用工具来处理,工具负责提取Annotation里包含的元数据,工具还会根据这些元数据增加额外的功能。在系统学习新的Annotation语法之前,先看一下Java提供的三个基本Annotation的用法:使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用,用于修饰它支持的程序元素。

  三个基本的Annotation如下:

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

1、基本注释

  @Override:表明该方法是重写父类的方法,eg:

class Test
{
@Override
public void func()
{
......
}
}
  @Deprecated:表示该类或方法已过时,程序使用这些类或方法时会发出编译警告。

  @SuppressWarnings:指示类或方法取消显示的编译警告,@SuppressWarnings中只有一个类型为String[]的元素成员value,其中常见的参数值为:

           1.deprecation:使用了不赞成使用的类或方法时的警告;
   2.unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 
   3.fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
   4.path:在类路径、源文件路径等中有不存在的路径时的警告; 
   5.serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告; 
   6.finally:任何 finally 子句不能正常完成时的警告; 
   7.all:关于以上所有情况的警告。

  使用示例:

@SuppressWarnings(value="unchecked")
public void func1()
{
List list = new ArrayList<Integer>();
list.add(10); //list没有指定泛型,此处会产生警告

List<String> ls = list; //将不带泛型的对象赋给带泛型的对象,产生警告,导致“堆污染”
System.out.println(ls.get(0));//该语句运行时产生异常
}
@SuppressWarnings({"unchecked", "deprecation"})
public void func2()
{

}
   @SafeVarargs:指示取消显示个数可变形参产生的警告,eg:

@SafeVarargs
public static void func3(List<String>...aryStringList) //个数可变的形参相当于是数组,因为没有泛型数组,所以形参相当于是一个List[],泛型被抹去,产生“堆污染”
{

}
  @FunctionalInterface:指示该接口是一个函数式接口(只有一个抽象方法,可以包含多个默认方法或静态方法的接口)。

2、自定义注释

 使用@interface来自定义一个注解,如下定义了名为Coder的注解,注解中包含两个元素personId(int类型)和company(String类型,默认值为"peking"):

public @interface Coder
{
int personId();
String city()default "peking";
}
  如果注释中仅包含一个元素,这个元素的名字应该为value,如:

public @interface Coder
{
String value();
}
  注释中可以包含枚举类型:

public @interface FruitColor 
{
public enum Color{ BULE,RED,GREEN}; //枚举
Color CoderColor() default Color.GREEN;
}
  声明(使用)自定义的注释的时候需要为其成员变量指定值,如果该变量无默认值的话:

@Coder(personId = 1001)
public void func()
{
......
}
  如果注释中元素的名字为value,那么在使用这个注解的时候,元素的名字和等号都可以省略,例如:

@Coder(“value”)
public void func()
{
......
}
  根据注解是否包含成员可以将注解分为标记注解(如@Override)和元注解(如@Retention)。

3、JDK的元注释

  在java.lang.annotation下有6个元Annotation,其中@Repeatable用于定义重复注解,其余5个用来修饰自定义的注解。

  @Retention:指定被修饰的Annotation保留的时间,通过指定其value成员变量的值:

//编译器把注释保存在class文件中,当运行java程序时,JVM不可获取注释信息,这是默认值。
@Retention(value = RetentionPolicy.CLASS)
@interface Testable{}

//编译器把注释保存在class文件中,当运行java程序时,JVM可以获取注释信息
//程序可以通过反射获取该注释
@Retention(value = RetentionPolicy.RUNTIME)
@interface Testable{}

//注释保存在源码中,编译器直接丢弃该注释。
@Retention(value = RetentionPolicy.SOURCE)
@interface Testable{}
  @Target:指定被修饰的Annotation能够修饰哪些程序单元,其成员value值常见的值有:

    ElementType.TYPE为指定该Annotation可以修饰类、接口(包括注解)、枚举定义。
    ElementType.CONSTRUCTOR为指定该Annotation只能修饰构造方法。
    ElementType.METHOD为指定该Annotation只能修饰方法定义。
    ElementType.FIELD为指定该Annotation只能修饰成员变量。

  @Documented:指定被修饰的Annotation将被javadoc工具提取成文档。

  @Inherited:指定被修饰的Annotation具有继承性,使用该Annotation的类的子类自动继承该Annotation。

  @Repeatable:在java 8之前,程序的元素(类、方法等)不能添加相同类型的注解,比如下面为使用两个@Result注解的实现方法:

@Results({@Result(name = "liyang"), @Result(name = "wulei")})
public void func()
{

}
    java 8中允许使用多个相同类型的注解,通过为注解添加@Repeatable修饰。

posted on 2019-05-08 21:36  HarryGreen  阅读(196)  评论(0编辑  收藏  举报