简单生活 趣味人生
  最后的告别 最后一个心愿是学会高飞

Java中的Annotation (一、系统内建的Annotatiion)

对于Annotation,是Java5以来的新特性,JDK5引入了Metadata(元数据)。所谓元数据就是关于数据的数据。注解就是代码的元数据,他们包含了代码自身的信息。注解可以被用在包,类,方法,变量,参数上。 Java中的Annotation就是一种元数据,它提供一些本来不属于程序的数据,比如:一段代码的作者或者告诉编译器禁止一些特殊的错误。被注解的代码并不会直接被注解影响。这只会向第三系统提供关于自己的信息以用于不同的需求。注解会被编译至class文件中,而且会在运行时被处理程序提取出来用于业务逻辑。当然,创建在运行时不可用的注解也是可能的,甚至可以创建只在源文件中可用,在编译时不可用的注解。

Annotation一般作为一种辅助途径,应用在软件框架或工具中,在这些工具类中根据不同的annontation注解信息采取不同的处理过程或改变相应程序元素(类、方法及成员变量等)的行为。

Annotation注解可以满足许多要求,最普遍的是:

  • 向编译器提供信息:注解可以被编译器用来根据不同的规则产生警告,甚至错误。一个例子是Java8中@FunctionalInterface注解,这个注解使得编译器校验被注解的类,检查它是否是一个正确的函数式接口。
  • 文档:注解可以被软件应用程序计算代码的质量例如:FindBugs,PMD或者自动生成报告,例如:用来Jenkins, Jira,Teamcity。
  • 代码生成:注解可以使用代码中展现的元数据信息来自动生成代码或者XML文件,一个不错的例子是JAXB。
  • 运行时处理:在运行时检查的注解可以用做不同的目的,像单元测试(JUnit),依赖注入(Spring),校验,日志(Log4j),数据访问(Hibernate)等等。

Annotation的核心的工作原理就是借助一个操作类通过反射的方式提取Annotation信息,进行操作。由此可见反射机制在java中用途广泛。

 

声明一个注解需要使用“@”作为前缀,这便向编译器说明,该元素为注解。

系统内建的 Annotation(元注解)

主要有以下几种:

@Override           // 声明某一个方法是用于覆盖父类中的方法,如果不是,就会在编译时报错

@Deprecated       //声明某一个方法 ,某一个类,不建议使用。已经过时。

@SuppressWarnings   //压制一些警告,比如泛型uncheck ,方法unuse

@Documented               //被注解的元素将会作为Javadoc产生的文档中的内容。注解都默认不会成为成为文档中的内容。这个注解可以对其它注解使用。

@Inherited       //在默认情况下,注解不会被子类继承。被此注解标记的注解会被所有子类继承。@Inheriated注解仅在存在继承关系的类上产生效果,在接口和实现类上并不工作。这条同样也适用在方               法,变量,包等等。只有类才和这个注解连用。

@Retention:这个注解注在其他注解上,并用来说明如何存储已被标记的注解。这是一种元注解,用来标记注解并提供注解的信息。可能的值是:

  • SOURCE                表明这个注解会被编译器忽略,并只会保留在源代码中。
  • CLASS:                     表明这个注解会通过编译驻留在CLASS文件,但会被JVM在运行时忽略,正因为如此,其在运行时不可见。
  • RUNTIME                   表示这个注解会被JVM获取,并在运行时通过反射获取。

@Target:这个注解用于限制某个元素可以被注解的类型。例如:

  • ANNOTATION_TYPE                  表示该注解可以应用到其他注解上
  • CONSTRUCTOR                        表示可以使用到构造器上
  • FIELD                                      表示可以使用到域或属性上
  • LOCAL_VARIABLE                    表示可以使用到局部变量上。
  • METHOD                                 可以使用到方法级别的注解上。
  • PACKAGE                                可以使用到包声明上。
  • PARAMETER                            可以使用到方法的参数上
  • TYPE                                      可以使用到一个类的任何元素上。

 

下面请看关于前三种注解的demo

1、@Override 

覆盖父类接口中未实现的抽象方法。

package com.iip;

interface Demo{    
   String getInfo();    
}

class Child implements Demo{
    @Override                  //覆盖父类中的方法
    public String getInfo(){
        return "child";
    }
}
public class AnnotationDemo {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Child d = new Child();        
        System.out.println(d.getInfo());
    }

}

2、@Deprecated 

直接在上面代码中@Override下面加入一行@Deprecated

class Child implements Demo{
    @Override
    @Deprecated
    public String getInfo(){
        return "child";
    }
}

通过javac编译就会发现  

提醒你使用了过时的API。

注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。

加入 -Xlint:deprecation 后再次编译

便提示了详细信息。

3、@SuppressWarnings

还是在上述代码中,在main函数上面加入@SuppressWarnings("deprecation")

    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Child d = new Child();        
        System.out.println(d.getInfo());
    }

再次编译将不会出现警告

或者也可以这样写 @SuppressWarnings(value={"deprecation"})

value接收的是一个数组,你可以加入多个参数,比如@SuppressWarnings(value={"deprecation","unchecked"})

 

@SuppressWarnings需要加入参数,这些参数都是已经定义好的了,定义的参数有如下几个。

deprecation   使用了过时的类或方法时的警告

unuse    定义的方法没用使用的警告

unchecked  执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型

fallthrough   当 Switch 程序块直接通往下一种情况而没有 Break 时的警告

path   在类路径、源文件路径等中有不存在的路径时的警告

serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告

finally    任何 finally 子句不能正常完成时的警告

all    关于以上所有情况的警告

 

明天将会继续学习如何构造自定义的Annotation。

 

posted @ 2015-01-19 13:31  MayDayIT  阅读(512)  评论(0编辑  收藏  举报