上一篇文章我们讲了注解的前两个:1.内置的注解 2.自定义注解 ,再回顾一下知识:
注解是Java的一种机制,允许开发人员向代码的不同部分附加信息,它并不是代码的一部分,因为它不会修改代码在运行时的行为,不会修改代码的语义。它主要用于对方法是否依赖方法、方法是否完整,类是否引用了其他类等给出提示信息帮助你编写正确代码。
分类:
1.内置的注解
2.自定义注解
3.为注解添加的注解
接下来继续接着讲剩下的内容:
三.为注解添加的注解
分类:
(1)Target
(2)Retention
(3)Documented
(4)Inherited
下面将分别进行介绍:
1.@Target
作用:用于指定代码中的哪些元素可以使用已定义类型的注解。
语法示例:
@Target(ElementType.METHOD)//指定Task注解只能用于方法
@interface Task{
String description();
}
除了ElementType.METHOD外,还可以指定以下类型及其作用:
ElementType.TYPE:可以应用于类的任何元素。
ElementType.FIELD:可以应用于字段(数据成员)。
ElementType.PARAMETER:可以应用于方法参数。
ElementType.CONSTRUCTOR:可以应用于构造函数。
ElementType.LOCAL_VARIABLE:可以应用于局部变量。
ElementType.ANNOTATION_TYPE:指出声明的类型本身是注解类型,即可以应用于注解类型。
2.@Retention
作用:用于设置注解的可见性。
可见性分为三个级别:编译器可见、工具可见、运行时可见
语法示例:
@Retention(RetentionPolicy.RUNTIME)
@interface Task{
}
其中RetentionPolicy枚举(用来设置注解的可见性)定义了三个常量:SOURCE、CLASS和RUNTIME,
(1)SOURCE:注解对编译器可见,对.class文件和运行时不可见。编译器可用此注解来检测错误和抑制警告,使用完后会丢弃注解。
(2)CLASS:注解对.class文件可见。
(3)RUNTIME:注解对.class文件和运行时可见。
运行时注解RUNTIME示例:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@WorkInProgress
public class RuntimeAnnotation {
@WorkInProgress
@Task(description="Implement tax",
estimatedHours=50,
additionalNote="This implement")
public static float computeTax(float amount,float rate){
return 0;
}
public static void main(String[]args){
try{
RuntimeAnnotation obj=new RuntimeAnnotation();
Class cls=obj.getClass();//返回对RuntimeAnnotation这个Class对象的引用
WorkInProgress wkAnnotation=(WorkInProgress)cls.getAnnotation(WorkInProgress.class);//获取WorkInProgress类型的注解,如果找不到则返回null
System.out.println("Class:"+cls.getName());
//检查cls这个元素(类)是否有注解
if(cls.isAnnotationPresent(WorkInProgress.class)){
System.out.println("\tThis class is not fully implemented.");
}
System.out.println("List of methods:");
Method[]methods=cls.getMethods();//内省对象cls,反射获取它的所有方法
for(Method method:methods){
System.out.println(method.getName());
if(method.isAnnotationPresent(WorkInProgress.class)){
System.out.println("\tThis method is not fully implemented.");
}
if(method.isAnnotationPresent(Task.class)){
Task tsAnnotation=(Task)method.getAnnotation(Task.class);
System.out.println(tsAnnotation.description()+" "+
tsAnnotation.targetDate()+" "+
tsAnnotation.estimatedHours()+" "+
tsAnnotation.additionalNote());
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
//以下是两个自定义的注解
@Retention(RetentionPolicy.RUNTIME)//设置注解的可见性是 运行时可见
@interface WorkInProgress{
}
@Retention(RetentionPolicy.RUNTIME)
@interface Task{
String description();
String targetDate() default "Jan 1,2012";
int estimatedHours();
String additionalNote();
}
运行结果:
Class:TestAnnotation.RuntimeAnnotation
This class is not fully implemented.
List of methods:
main
computeTax
This method is not fully implemented.
Implement tax Jan 1,2012 50 This implement
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
3.@Documented
作用:表示javadoc工具应该为带有这种类型的注解生成文档。它是一种Marker类型的注解,没有任何成员。
注:javadoc是JDK中包含的文档生成器,用于从Java源代码生成HTML格式的API文档。
例如我为前面的WorkInProgress和Task两个注解前都加上@Documented注解之后,使用javadoc工具为RuntimeAnnotation.java文件生成API文档后打开查看ComputeTax方法,结果如下:
可以看到,两个注解WorkInProgress和Task都有对应的文档。
4.@Inherited
当子类继承父类时,在默认情况下时不会继承父类的注解的,而使用@Inherited对父类的注解进行注解后,子类会继承父类的注解。
例如:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface WorkInProgress{
}
然后RuntimeAnnotation父类使用了WorkInProgress的注解:
@WorkInProgress
public class RuntimeAnnotation {
接着使用子类RunAnnotation继承父类RuntimeAnnotation:
public class RunAnnotation extends RuntimeAnnotation{
此时子类RunAnnotation继承父类RuntimeAnnotation的注解WorkInProgress。