详解Java注解(下)

上一篇文章我们讲了注解的前两个: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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章