[size=small]Annotation
Annotation 提供了一条与程序元素关联任何信息或者任何元数据(metadata)的途径。从某些方面看,annotation就像修饰符一样被使用,并应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在annotation的“name=value”结构对中。为程序在编译、运行时提供一定的信息,做相应的处理。
annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息,且annotaion不影响程序代码本身的执行。
a.JDK内置的annotation ,api有对应的annotation类型说明 :
Marker Annotation 标示 ,名称本身已提供修饰所要表达的信息,因此不需要参数,类似于Serializable接口 : @override(覆写)、@Deprecated(不建议使用);
@SuppressWarnings()去除编译时警告,参数定义“被去除的警告类型”
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked","deprecation"}) {}:代表数组
b.自定义annotation
# 语法
public @interface AnnotationTest {
String msg() default "hello";
String value();
String[] names() default {"shi","Jim"};
}
注意点:
1、“空”体的Annotation是Marker类型,与@Override相同。
2、value是默认的annotation属性。区别在于使用 :@AnnotationTest("hello") ,但其它名称的属性必须制定名称,如 @AnnotationTest(msg="hello")
3、数组的指定,使用{},各属性之间以“,”分割。
4、default关键字指定“默认值”。
5、annotation体内允许的数据类型为 :primitive type , String , Class , Annotation , enum , 一维数组。
6、annotation的定义与使用类位于不同包,需导入annotation。因此可通过“包”管理annotation的结构。
7、定义Annotation,不能继承其它的Annotation型态或接口。
关键点:
使用@interface定义annotation型态时,实际自动继承了java.lang.annotation 包的Interface Annotation 接口。编译器自动完成了其它的细节。
翻译 :所有的Annotation类型都继承此公共接口。注意,如果一个接口显示的继承此接口,并不能定义一个Annotation类型 ;且此接口也没有定义一个Annotation类型(仅为普通接口)。
C、Annotation的处理方式(重点)
编译器、JVM怎么处理注解呢?从下面这个例子 :
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
从JDK内置的Override,看到这样一个属性“Retention”,翻译为:保持力、记忆。就是说annotation提供的信息的生命周期由Retention决定。
翻译大意:指明annotation存储的类型。如果一个annotation没有声明Retention,默认的存储策略为Class。
结论 :重点在于RUNTIME策略,众多流行的框架对注解的使用都利用此特性。
D、结合Reflect对Annotation读取访问
提供Annotation信息的主要接口 : java.lang.reflect Interface
翻译大意:代表目前程序元素在运行时拥有的注解,此接口运行通过反射读取注解信息。在此接口的方法返回的注解是不变的,序列化的。
Demo :项目TestIdea下的com.anonation.reflect包 (仅提醒自己)
E、@Target :指明annotation被用于那种程序元素,不声明Target时默认为任何程序元素。
翻译大意:指明annotation被用于程序的那种元素。如果一个annotation的Target属性没有被声明,则这个定义的annotation类型可以被用于任何程序元素。如果一个annotation的Target属性被声明,编译器则强制约束此annotation的用法。
具体的ANNOTATION_TYPE,请参考java.lang.annotation Enum ElementType 。
F、补充Annotation与JavaDoc
采用@Documented,使通过javadoc生成的文档包含此Annotation的信息。
G、补充Annotation的继承问题
翻译大意 :表明Annotation类型被自动继承。注意,只有Annotation被用于类时,继承才会生效。
注 :根据风中叶老师的Annotation视频,学习记录。谢谢风中叶老师。[/size]
Annotation 提供了一条与程序元素关联任何信息或者任何元数据(metadata)的途径。从某些方面看,annotation就像修饰符一样被使用,并应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在annotation的“name=value”结构对中。为程序在编译、运行时提供一定的信息,做相应的处理。
annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息,且annotaion不影响程序代码本身的执行。
a.JDK内置的annotation ,api有对应的annotation类型说明 :
Marker Annotation 标示 ,名称本身已提供修饰所要表达的信息,因此不需要参数,类似于Serializable接口 : @override(覆写)、@Deprecated(不建议使用);
@SuppressWarnings()去除编译时警告,参数定义“被去除的警告类型”
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked","deprecation"}) {}:代表数组
b.自定义annotation
# 语法
public @interface AnnotationTest {
String msg() default "hello";
String value();
String[] names() default {"shi","Jim"};
}
注意点:
1、“空”体的Annotation是Marker类型,与@Override相同。
2、value是默认的annotation属性。区别在于使用 :@AnnotationTest("hello") ,但其它名称的属性必须制定名称,如 @AnnotationTest(msg="hello")
3、数组的指定,使用{},各属性之间以“,”分割。
4、default关键字指定“默认值”。
5、annotation体内允许的数据类型为 :primitive type , String , Class , Annotation , enum , 一维数组。
6、annotation的定义与使用类位于不同包,需导入annotation。因此可通过“包”管理annotation的结构。
7、定义Annotation,不能继承其它的Annotation型态或接口。
关键点:
使用@interface定义annotation型态时,实际自动继承了java.lang.annotation 包的Interface Annotation 接口。编译器自动完成了其它的细节。
public interface Annotation :
The common interface extended by all annotation types. Note that an interface that manually extends this one does not define an annotation type. Also note that this interface does not itself define an annotation type.
翻译 :所有的Annotation类型都继承此公共接口。注意,如果一个接口显示的继承此接口,并不能定义一个Annotation类型 ;且此接口也没有定义一个Annotation类型(仅为普通接口)。
C、Annotation的处理方式(重点)
编译器、JVM怎么处理注解呢?从下面这个例子 :
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
从JDK内置的Override,看到这样一个属性“Retention”,翻译为:保持力、记忆。就是说annotation提供的信息的生命周期由Retention决定。
java.lang.annotation Annotation Type Retention
________________________________________
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Retention
Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS.
A Target meta-annotation has effect only if the meta-annotated type is use directly for annotation. It has no effect if the meta-annotated type is used as a member type in another annotation type.
翻译大意:指明annotation存储的类型。如果一个annotation没有声明Retention,默认的存储策略为Class。
java.lang.annotation.RetentionPolicy
________________________________________
public enum RetentionPolicy
extends Enum<RetentionPolicy>
Annotation retention policy. The constants of this enumerated type describe the various policies for retaining annotations. They are used in conjunction with the Retention meta-annotation type to specify how long annotations are to be retained.
________________________________________
Enum Constant Summary
CLASS
Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.(编译后注解被存储在class文件中,但不需要在运行时被JVM读取存储)
RUNTIME
Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.(编译后注解被存储在class文件中,且在运行时被JVM读取,因此可以通过反射动态获取注解提供的信息)
SOURCE
Annotations are to be discarded by the compiler.(编译后注解被丢弃,即注解信息只存在于源文件)
结论 :重点在于RUNTIME策略,众多流行的框架对注解的使用都利用此特性。
D、结合Reflect对Annotation读取访问
提供Annotation信息的主要接口 : java.lang.reflect Interface
AnnotatedElement
All Known Implementing Classes :
AccessibleObject, Class, Constructor, Field, Method, Package
(Class、Filed、Method都实现了AnnotatedElement接口,通过反射得到方法Method对象等,再通过AnnotatedElement接口提供的方法就可以获取Annotation的提供的所有信息)
________________________________________
public interface AnnotatedElement
Represents an annotated element of the program currently running in this VM. This interface allows annotations to be read reflectively. All annotations returned by methods in this interface are immutable and serializable.
翻译大意:代表目前程序元素在运行时拥有的注解,此接口运行通过反射读取注解信息。在此接口的方法返回的注解是不变的,序列化的。
Demo :项目TestIdea下的com.anonation.reflect包 (仅提醒自己)
E、@Target :指明annotation被用于那种程序元素,不声明Target时默认为任何程序元素。
java.lang.annotation Annotation Type Target
________________________________________
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Target
Indicates the kinds of program element to which an annotation type is applicable. If a Target meta-annotation is not present on an annotation type declaration, the declared type may be used on any program element. If such a meta-annotation is present, the compiler will enforce the specified usage restriction.
翻译大意:指明annotation被用于程序的那种元素。如果一个annotation的Target属性没有被声明,则这个定义的annotation类型可以被用于任何程序元素。如果一个annotation的Target属性被声明,编译器则强制约束此annotation的用法。
具体的ANNOTATION_TYPE,请参考java.lang.annotation Enum ElementType 。
F、补充Annotation与JavaDoc
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
String desc();
}
采用@Documented,使通过javadoc生成的文档包含此Annotation的信息。
G、补充Annotation的继承问题
java.lang.annotation Annotation Type Inherited
________________________________________
Indicates that an annotation type is automatically inherited.
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
翻译大意 :表明Annotation类型被自动继承。注意,只有Annotation被用于类时,继承才会生效。
注 :根据风中叶老师的Annotation视频,学习记录。谢谢风中叶老师。[/size]