参考:http://www.cnblogs.com/skywang12345/p/3344137.html
http://www.cnblogs.com/taoxiaoji/archive/2011/01/19/1939651.html
http://blog.csdn.net/tigerdsh/article/details/8848890
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
首先知道注解是什么,能干什么,在什么时候用?
1.是什么注解?
即一种对数据的描述。为我们在代码中 添加信息 提供了一种 形式化 的 方法,是我们可以在 稍后 某个时刻 方便地使用这些数据(java虚拟机 通过 解析注解 来使用这些数据)。即它是一种对数据的描述。
2.注解能干什么?
- 生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
- 跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。
- 在编译时进行格式检查。如 @override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
它也是一种注释,不过它不只有注释的意义。可能你会觉得有点抽象。我们还是使用 @override 举例,如果它标记了某个方法不是重写了它的父类的方法,那么在编译时就会报错。这不就是对方法(你可以理解方法也是一种数据)描述吗?这种描述相当于某种限定,超出限定会抛出相应的异常,可以更加快捷、方便的编码,减少代码量。
3.怎么用注解?
3.1 注解的定义:使用 @interface
modifiers @interface AnnotationName { element declaration1; element declaration2; }
modifiers : private、public、protect、default
AnnotationName:自定义注解的名称,类似于类名。
element:注解元素的类型
declaration1、declaration2:注解元素的名称
3.2 注解中元素的 声明 和 定义
注解参数的可支持数据类型:
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组
1. type elementName(); 2. type elementName() default value;
看到这里,你已经知道如何自定义注解了吧。
在创建自定义注解之前,我们先看看java中的 java.lang.annotation 包的类组成:
1)Annotation:所有的注解 都继承 Annotation 接口,就相当于 Java 中的所有类,都是继承与 Object 类。
2)AnnotationFormatError、AnnotationTypeMismatchException、IncompleteAnnotationException:这3个类都是 自定义异常。
3)ElementType、RetentionPolicy:两个枚举类型。
ElementType:用于描述注解的使用范围,限定注解标记的对象,总共有 8 种。
public enum ElementType { //此值对应修饰:类,接口(包括注解类型),枚举类型 TYPE, //此值对应修饰:属性(包括枚举常量) FIELD, //此值对应修饰:方法 METHOD, //此值对应修饰:方法中的参数 PARAMETER, //此值对应修饰:构造方法 CONSTRUCTOR, //此值对应修饰:局部变量 LOCAL_VARIABLE, //此值对应修饰:注解 ANNOTATION_TYPE, //此值对应修饰:包 PACKAGE
}
RetentionPolicy:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
public enum RetentionPolicy { //注解将被编译器丢弃 SOURCE, //注解在class文件中可用,但会被VM(虚拟机)丢弃 CLASS, //VM(虚拟机)将在运行期也保留注释,因此可以通过反射机制读取注解的信息。 RUNTIME }
4)Target、Retention、Documented、Inherited:4个元注解,可能看到这里,不知到元注解是个什么东东?继续往下看。
Target:用于限定 注解标记的对象。
@Documented @Retention(RetentionPolicy.RUNTIME)//限定 @Target(ElementType.ANNOTATION_TYPE)//限定 Target 注解,只用标记 注解。 public @interface Target { ElementType[] value(); //Target注解的元素,类型为ElementType[],名称为 value
}
看到这里,你会发现 Target 注解的元素,是之前定义的枚举类型 ElementType的数组,里边可以是多个值。所以 Target 是用于 限定 注解 标记的范围,然后值是ElementType中的一个或者多个!
那么元注解的定义:只能标记注解的注解,换句话说,所有的元注解只能标记注解,也就是 @Target 的值是 ElementType.ANNOTATION_TYPE
Retention:用于限定 注解 的 在什么级别有效
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }
跟 Target 类似,Retention注解中元素的值是枚举类型 RetentionPolicy 的值,值只能是 RetentionPolicy 的一个,only one !!!
Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }
Inherited:是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }
到此,是不是对 java 注解 有一个初步的认识了,这肯定是不够的,最好的学习方法就是使用它!!!
至于例子可以直接看这篇博客 (http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html)很详细!