1、源码简介
Java annotation的源码主要在 java.lang.annotation包下面;
1.1 Annotation接口
不多说先上源码
/**
* The common interface extended by all annotation types. Note that an
* interface that manually extends this one does <i>not</i> define
* an annotation type. Also note that this interface does not itself
* define an annotation type.
*
* @author Josh Bloch
* @since 1.5
*/
/**
* 首先声明英语不是很好,大致意思是:这是一个基础接口,所有的注解类型都继承与它。但是需要注意的是
* (1)不需要手动指明一个注解类型是继承与它的(意思是自动继承)
* (2)它本身不是注解类型
*/
public interface Annotation {
/**
* 这三个方法就不用多说了吧!
*/
boolean equals(Object obj);
int hashCode();
String toString();
/**
* Returns the annotation type of this annotation.
*/
/**
* 返回注解的class
*/
Class<? extends Annotation> annotationType();
}
/**
* The common interface extended by all annotation types. Note that an
* interface that manually extends this one does <i>not</i> define
* an annotation type. Also note that this interface does not itself
* define an annotation type.
*
* @author Josh Bloch
* @since 1.5
*/
/**
* 首先声明英语不是很好,大致意思是:这是一个基础接口,所有的注解类型都继承与它。但是需要注意的是
* (1)不需要手动指明一个注解类型是继承与它的(意思是自动继承)
* (2)它本身不是注解类型
*/
public interface Annotation {
/**
* 这三个方法就不用多说了吧!
*/
boolean equals(Object obj);
int hashCode();
String toString();
/**
* Returns the annotation type of this annotation.
*/
/**
* 返回注解的class
*/
Class<? extends Annotation> annotationType();
}
真心觉得这个接口中没什么好说的!
1.2 ElementType和Target
@Target
限定Annotation所修饰的对象范围,范围包括packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标,一句话,这个Annotation可以用在什么地方。
可用的取值(ElementType)有:
CONSTRUCTOR:用于描述构造器
FIELD: 用于描述域
LOCAL_VARIABLE: 用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明
/**
* A program element type. The constants of this enumerated type
* provide a simple classification of the declared elements in a
* Java program.
*
* <p>These constants are used with the {@link Target} meta-annotation type
* to specify where it is legal to use an annotation type.
*
* @author Joshua Bloch
* @since 1.5
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE
}
/**
* A program element type. The constants of this enumerated type
* provide a simple classification of the declared elements in a
* Java program.
*
* <p>These constants are used with the {@link Target} meta-annotation type
* to specify where it is legal to use an annotation type.
*
* @author Joshua Bloch
* @since 1.5
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
1.3 RetentionPolicy和Retention
这两个类表明了注解的生命周期;
SOURCE:在源文件中有效(即源文件保留)--出现在源代码中,而被编译器丢弃。
CLASS:在class文件中有效(即class保留)--被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略。
RUNTIME:在运行时有效(即运行时保留)--其被编译到class中,并在运行时,被读取和使用的。
/**
* Annotation retention policy. The constants of this enumerated type
* describe the various policies for retaining annotations. They are used
* in conjunction with the {@link Retention} meta-annotation type to specify
* how long annotations are to be retained.
*
* @author Joshua Bloch
* @since 1.5
*/
/**
* 指明注解的保留策略,和元注解Retention配合使用
*/
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
/**
* 是不是很熟悉,就是上面说道的,分别表示:
* SOURCE:表明这个注解编译是就丢弃了,不会编译到class文件中;
* CLASS:表明这个注解会被编译到Class文件中,但是在VM中运行时丢弃;
* RUNTIME:这个是最常用的,表明注解会被保留到VM运行中;
*/
}
/**
* Annotation retention policy. The constants of this enumerated type
* describe the various policies for retaining annotations. They are used
* in conjunction with the {@link Retention} meta-annotation type to specify
* how long annotations are to be retained.
*
* @author Joshua Bloch
* @since 1.5
*/
/**
* 指明注解的保留策略,和元注解Retention配合使用
*/
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
/**
* 是不是很熟悉,就是上面说道的,分别表示:
* SOURCE:表明这个注解编译是就丢弃了,不会编译到class文件中;
* CLASS:表明这个注解会被编译到Class文件中,但是在VM中运行时丢弃;
* RUNTIME:这个是最常用的,表明注解会被保留到VM运行中;
*/
}
/**
* 这是基础的元注解,用于表示注解的保留策略
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
/**
* 这是基础的元注解,用于表示注解的保留策略
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
1.4 Documented
描述其它类型的annotation被作为被标注的程序成员的公共API,从而被javadoc此类的工具文档化。
/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
/**
* Indicates that annotations with a type are to be documented by javadoc
* and similar tools by default. This type should be used to annotate the
* declarations of types whose annotations affect the use of annotated
* elements by their clients. If a type declaration is annotated with
* Documented, its annotations become part of the public API
* of the annotated elements.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
1.5 Inherited
源代码很简单,但是我对这个继承标注真的弄得不是很清楚。以后在研究吧
指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。
注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
1.6 AnnotationFormatError、AnnotationTypeMismatchException、IncompleteAnnotationException
AnnotationFormatError:当注释分析器试图从类文件读取注释并确定注释出现异常时,抛出该错误。
AnnotationTypeMismatchException:若某个注释的类型在对该注释进行编译(或序列化)后发生了更改,而程序试图访问该注释的元素时,抛出此异常。
IncompleteAnnotationException:若某个注释在编译(或序列化)后将某个注释类型添加到其类型定义中,而程序试图该注释类型的元素时,抛出此异常。如果新元素有默认值,则不抛出此异常。
2、示例
(1)定义注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Description {
String value();
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Description {
String value();
}
(2)使用注解
@Description("Description say \"Hello Word\"")
public class Description_Test {
}
@Description("Description say \"Hello Word\"")
public class Description_Test {
}
(3)实现注解
public class TestAnnotation {
public static void main(String[] args) throws Exception {
String CLASS_NAME = "com.shyann.jvm.annotation.Description_Test";
Class<?> clz = Class.forName(CLASS_NAME);
boolean flag = clz.isAnnotationPresent(Description.class);
if (flag) {
Description description = clz.getAnnotation(Description.class);
System.out.println(description.value());
}
}
}
public class TestAnnotation {
public static void main(String[] args) throws Exception {
String CLASS_NAME = "com.shyann.jvm.annotation.Description_Test";
Class<?> clz = Class.forName(CLASS_NAME);
boolean flag = clz.isAnnotationPresent(Description.class);
if (flag) {
Description description = clz.getAnnotation(Description.class);
System.out.println(description.value());
}
}
}
3、分析
个人觉得要分析的有两个方法isAnnotationPresent()和getAnnotation()
在Class类中找到了这两个方法
public boolean isAnnotationPresent(
Class<? extends Annotation> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
return getAnnotation(annotationClass) != null;
}
public boolean isAnnotationPresent(
Class<? extends Annotation> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
return getAnnotation(annotationClass) != null;
}
好吧原来弄到底还是只有getAnnotation()这一个方法啊
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
initAnnotationsIfNecessary();//初始化
return (A) annotations.get(annotationClass);
}
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
initAnnotationsIfNecessary();//初始化
return (A) annotations.get(annotationClass);
}
//看了下这个方法。基本上就是扫描后放入到annotations中,完成初始话!
private synchronized void initAnnotationsIfNecessary() {
clearCachesOnClassRedefinition();//看了下这个方法,好像是清理缓存用的。
if (annotations != null)
return;
declaredAnnotations = AnnotationParser.parseAnnotations(
getRawAnnotations(), getConstantPool(), this);//这个方法没法找到啊
Class<?> superClass = getSuperclass();
if (superClass == null) {
annotations = declaredAnnotations;
} else {
annotations = new HashMap<Class, Annotation>();
superClass.initAnnotationsIfNecessary();
for (Map.Entry<Class, Annotation> e : superClass.annotations.entrySet()) {
Class annotationClass = e.getKey();
if (AnnotationType.getInstance(annotationClass).isInherited())
annotations.put(annotationClass, e.getValue());
}
annotations.putAll(declaredAnnotations);
}
}
//看了下这个方法。基本上就是扫描后放入到annotations中,完成初始话!
private synchronized void initAnnotationsIfNecessary() {
clearCachesOnClassRedefinition();//看了下这个方法,好像是清理缓存用的。
if (annotations != null)
return;
declaredAnnotations = AnnotationParser.parseAnnotations(
getRawAnnotations(), getConstantPool(), this);//这个方法没法找到啊
Class<?> superClass = getSuperclass();
if (superClass == null) {
annotations = declaredAnnotations;
} else {
annotations = new HashMap<Class, Annotation>();
superClass.initAnnotationsIfNecessary();
for (Map.Entry<Class, Annotation> e : superClass.annotations.entrySet()) {
Class annotationClass = e.getKey();
if (AnnotationType.getInstance(annotationClass).isInherited())
annotations.put(annotationClass, e.getValue());
}
annotations.putAll(declaredAnnotations);
}
}
4、其实感觉只是很low的看了下源代码。真正核心的没有看到。以后能看到在看吧!