annotation 的文档真是不少,有兴趣的同学可以看看 cleverpig 翻译的tutorial,很好的:
JavaAnnotation 入门: http://www.matrix.org.cn/resource/article/2005-12-21/Java+Annotation+Apt_44062.html
JavaAnnotation 手册: http://www.blogjava.net/mlh123caoer/archive/2007/09/06/143260.html
JavaAnnotation高级应用: http://www.matrix.org.cn/resource/article/2005-12-21/Java+Annotation+Apt_44062.html
基本够看一个上午的,看来礼拜六的上午就交代这了
总结了一下:
java.lang.annotation
@Retention RetentionPolicy如果自定义的annontaion @Retention默认值为 RetentionPolicy.CLASS
@Target ElementType
annotation中能定义类似于接口中的方法,并且这些方法必须为无参数且无异常抛出的方法,
方法的返回值必须是编译时常量,可以是基本类型、String、Class、annotation、枚举和一维数组,
方法的后面可以使用 default和一个默认数值来声明成员的默认值,null不能作为成员默认值
annotation 也可以定义常量、静态成员类型(比如枚举类型定义),可以如接口一般被实现或者继承
不过 第二篇里对@Inherited 没有说的那么清楚,补充一下:
jdk doc 中说
package java.lang.annotation;
/**
* Indicates that an annotation type is automatically inherited. If
* an Inherited meta-annotation is present on an annotation type
* declaration, and the user queries the annotation type on a class
* declaration, and the class declaration has no annotation for this type,
* then the class's superclass will automatically be queried for the
* annotation type. This process will be repeated until an annotation for this
* type is found, or the top of the class hierarchy (Object)
* is reached. If no superclass has an annotation for this type, then
* the query will indicate that the class in question has no such annotation.
*
* <p>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.
*
* @author Joshua Bloch
* @since 1.5
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
可以看出 @Inherited 只能用来修饰 自定义的Annotation,并且只有在修饰类时,
才能达到继承的效果,i.e. 修饰类的Annotation默认是不继承的,只有使用@Inherited
时,才有继承效果。说的抽象,代码实际:
## 定义一个 Annotation:
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AA {
String name();
}
~
## 使用这个Annotation
@AA(name="haha")
public class UseAA {
public static void main(String[] args) {
AA annotation = UseAA.class.getAnnotation(AA.class);
System.out.println(null == annotation ? null : annotation.name());
}
} // java UseAA 输出 haha
## UseAA 的派生类中, @AA 不能被反射使用
public class SubUseAA extends UseAA {
public static void main(String[] args ) {
AA aa = SubUseAA.class.getAnnotation(AA.class);
System.out.println(null == aa ? null : aa.name());
}
} // java SubUseAA 输出 null
如果为 @interface AA 添加 @Inherited 就可以输出 haha 了,i.e. 把 @AA 修改为
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AA {
String name();
}
注意:只需要 javac AA.java 就可以,无须重新编译 UseAA.java 和 SubUseAA.java,
java SubUseAA 就可以输出 haha
修饰方法的 注解,无须使用@Inherited来修饰,也可以被继承的