anotation学习笔记

一.Annotation是什么:Annotation提供一种机制,将程序的元素如:类,方法,属性,参数,本地变量,包和元数据联系起来。我的理解是,Annotation给这些程序的元素增加额外的信息注释,编译器在编译时根据约定处理JDK内置的基本注释,比如@Override@Deprecated等。我们也可以在运行时获取这些元素上的信息,然后根据这些信息来执行不同的操作。

 

二.Annotation作用:1.编写文档,通过代码里标识的元数据生成文档;2.代码分析,通过代码里标识的元数据对代码进行分析;3.编译检查,通过代码里标识的元数据让编译器能实现基本的编译检查;4.使用Annotation部分代替XML文件来配置运行参数。

 

三.Java内置的Annotation

1@Override定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;代码如下:

public class OverrideDemo {

    @Override

public String tostring() {

        return super.toString();

    }

}

在编译时,会提示以下错误信息:

OverrideTest.java:4: 方法未覆盖其父类的方法

        @Override

         ^1 错误

eclipse中,红叉叉会告诉你,要去掉方法的Override注释

2@Deprecated定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。使用@Deprecated的示例代码如下:

public class DeprecatedDemo {

    public static void main(String[] args) {

         DeprecatedClass.DeprecatedMethod();

    }

}

 

class DeprecatedClass {

    @Deprecated

    public static void DeprecatedMethod() {

        // TODO

    }

}

在编译时,会得到以下提示信息:

注意:DeprecatedDemo.java 使用或覆盖了已过时的 API

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

 3@SuppressWarnings定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:

参数

说明

deprecation

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

unchecked

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

fallthrough

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

path

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

serial

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

finally

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

all

关于以上所有情况的警告

通过上面的表格,你应该了解到每个参数的用意了,下面我就以一个常用的参数unchecked为例,为你展示如何使用@SuppressWarnings注释,示例代码如下:

import java.util.List;

import java.util.ArrayList;

public class SuppressWarningsDemo {

        public static List cache = new ArrayList();

        //@SuppressWarnings(value = "unchecked")

        public void add(String data) {

            cache.add(data);

        }

}

当我们不使用@SuppressWarnings注释时,编译器就会有如下提示:

注意:SuppressWarningsDemo.java 使用了未经检查或不安全的操作。

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

下面我们去掉@SuppressWarnings(value="unchecked")这一行的注释符“//”,它会屏蔽编译时的警告信息,这也就是它所要达到的目的。

 

四.自定义简单的Annotation

 定义一个Annotation是采取的是类似于Interface的定义方式:

@Retention这个元注释(meta-annotation)表示我们创建的TestAnnotation这个Annotation将会存储在Class文件中,并在javaVM运行时加载它。Retention描述了这个注释在程序中会保存多久,由RetentionPolicy中的值来指定, RetentionPolicy有三个值:

可以看到,默认情况下是CLASS类型,这种类型会把注释信息保存入.class文件中,但我们是不能在运行时取到注释中的信息的。而SOURCE类型的注释只是用于编译时的检查等,不会保存如.class文件中,RUNTIME类型的注释会被保存入.class文件中,并且在运行时刻能够得到注释中的信息(关于CLASSRUNTIME两种类型的区别,在后面证明)。@Target指定了TestAnnotation将用来描述的程序中元素的类型(类,方法,属性,参数,本地变量,包和元数据)。

         TestAnnotation同时定义了两个成员,namenotice,都是String类型,有一点需要注意的是,如果只有一个成员,推荐这个成员写成value。在使用时,以如图的方式给他们赋值,而且,当只有一个成员时,可以写成@TestAnnotation(“the value”)的形式。(ps:如果不想每次都去给某一些成员赋值,可以对指定的成员赋初值,形式如:【String name() default “tang”】)

使用annotation

 

五.运行时解析annotation

1.创建一个TradeMarker注释,其中有nameowner两个值

2.创建一个License注释,其中包含namenoticeredistribute值,还包含了对TradeMarker注释的引用。

3.在类上使用License注释,并使用反射来得到注释中的信息

AnnotatedElement接口位于 java.lang.reflect 程序包中并由ClassConstructorFieldMethodPackage等类实现,所以在程序中,可以使用这些元素的getAnnotation方法得到注释在他们之上的annotation,进而得到annotation的值,那么,这样可以实现根据annotation来进行运行参数的配置。

你可能感兴趣的:(String,generics,Class,Constructor,编译器,deprecated)