第一部分:了解一下java1.5起默认的三个annotation类型:
Jdk1.5引入了一种原语言工具,叫“annotation”。Annotation提供的信息不是程序的一部分,例如代码片断的作者,或者告诉编译器忽略特定的错误等,annotation不会对程序的运行产生任何影响。
Annotation的形式为:@annotation。它可以被应用到类,属性,方法等的声明处。Annotation位于他们之前,并且(通常)独立一行。它还可以带有参数,例如:
@Author("MyName")
class myClass {}
或者
@SuppressWarnings("unchecked")
void MyMethod() {}
Java1.5自带的三个annotation类型:
1、@Override:
只能用在方法之上的。表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
代码清单:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}
2、@Deprecated:
用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
代码清单:
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {}
3、@SuppressWarnings:
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示 的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。
根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。
代码清单:
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
对以上三个annotation的类型使用举例:
import java.util.List;
class Food {}
class Hay extends Food {}
class Animal {
Food getPreferredFood() {
return null;
}
/**
* @deprecated document why the method was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
}
class Horse extends Animal {
Horse() {
return;
}
@Override
Hay getPreferredFoods() /* The method getPreferredFoods() of type Horse must override a superclass method Horse.java*/
return new Hay();
}
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
Animal.deprecateMethod(); //deprecation warning - suppressed
}
}
第二部分:了解annotation的概念,设计自己的annotation.
1、 首先在jdk自带的java.lang.annotation包里的几个类源文件
A、Documneted的源文件:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。
源码解读:其中的@interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字
B、Inherited的源文件
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {}
功能描述:指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此 类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。
注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。
B、 Retention的源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
功能说明:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。
在上面的文件用到RetentionPolicy、ElementType两个子段,这两个子段的说明如下。
A)、RetentionPolicy
源码文件:
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
功能描述:注释保留策略。此枚举类型的常量描述保留注释的不同策略,他们与Retention元注释一起使用,以指定保留多长的注释。
SOURCE:Annotation类型的信息只会保留在程序源码里,源码如果经过了编译之后,Annotation的数据就会消失
CLASS:Annotation类型的信息保留在程序源码里,同时也会保留在编译好的.class文件里面,在执行的时候,并不会把这一些信息加载到虚拟机(JVM)中去。
RUNTIME:表示在源码、编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的
B)ElementType:
源码文件:
public enum ElementType {
TYPE, //类型 TYPE(类型)是指可以用在Class,Interface,Enum和Annotation类型上
FIELD,//属性
METHOD,//方法
PARAMETER,//参数
CONSTRUCTOR,//构造函数
LOCAL_VARIABLE,//局部变量
ANNOTATION_TYPE,
PACKAGE//注释类型声明
}
功能描述:序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。 这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。
第三部分:下面设计一个自己最简单的Annotation例子,这一例子共用四个文件
1、Description的代码清单:
package annotation2;
import java.lang.annotation.*;
/*
说明:所有的Annotation会自动继承java.lang.annotation这一个接口,所以不能再去继承别的类或是接口.
最重要的一点,Annotation类型里面的参数该怎么设定:
第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型.
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String.
第三,如果只有一个参数成员,参数名称一定要为"value",后加小括号.例:上面的例子就只胡一个参数成员.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface