跟王老師學註解(五):利用反射讀取註解信息

跟王老師學註解(五):讀取註解信息

主講教師:王少華   QQ羣號:483773664

一、註解被讀取

(一)條件

當一個註解類型被定義爲運行時註解後,該註解纔是運行時可以見,當class文件被裝載時被保存在class文件中的註解纔會被Java虛擬機所讀取。

要把@Retention註解的value成員變量的值設爲RetentionPolicy.RUNTIME

(二)辦法

我們已知所有的註解都是繼承的java.lang.Annotation接口,也就是說Annotation是所有接口的父接口。除此之外,在java.lang.reflect包下的新增了AnnotatedElement接口,該接口代表程序中可以接受註解的程序元素,


1、該接口有如下幾個實現類,分別是:

Class:類定義

Constructor:構造方法定義

Field:類的成員變量定義

Method:類的方法定義

Package:類的包定義


2、java.lang.reflect.AnnotatedElement接口是所有程序元素的父接口,程序通過反射獲得某個類的AnnotatedElement對象,調用該對象的3個方法就可以來訪問註解信息。

getAnnotation()方法:用於返回該程序元素上存在的、指定類型的註解,如果該類型的註解不存在,則返回null

getAnnotations():用來返回該程序元素上存在的所有註解。

isAnnotationPresent():用來判斷該程序元素上是否包含指定類型的註解,如果存在返回true,否則返回false.


二、示例

(一)輸出類方法上的所有註解

1、自定義的annotation

1
2
3
4
5
6
7
8
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,
    ElementType.PARAMETER, ElementType.CONSTRUCTOR,
    ElementType.LOCAL_VARIABLE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String name() default "Jack";
    int age() default 20;
}

2、使用自定義Annotation

1
2
3
4
5
6
7
8
public class Person {
    private String name;
    private int age;
    @MyAnnotation
    public void setInfo(){
         
    }
}

3、測試

1
2
3
4
5
6
7
8
9
10
public class AnnotationTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
        Class<Person> personClass = (Class<Person>) Class.forName("chapter10_04.Person");
        Method method = personClass.getMethod("setInfo");
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

(二)獲取某個註解裏的元數據

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AnnotationTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
        Class<Person> personClass = (Class<Person>) Class.forName("chapter10_04.Person");
        Method method = personClass.getMethod("setInfo");
        Annotation[] annotations = method.getAnnotations();
        for (Annotation annotation : annotations) {
            //如果類型是MyAnnotation
            if (annotation instanceof MyAnnotation) {
                System.out.println(annotation);
                //強制類型轉換
                MyAnnotation myAnnotation = (MyAnnotation) annotation;
                //輸出值
                System.out.println("myAnnotation.name:"+myAnnotation.name());
                System.out.println("myAnnotation.age:"+myAnnotation.age());
            }
        }
    }
}

三、@Inherited

@Inherited : 在您定義註解後並使用於程序代碼上時,預設上父類別中的註解並不會被繼承至子類別中,您可以在定義註解時加上java.lang.annotation.Inherited 限定的Annotation,這讓您定義的Annotation型別被繼承下來。注意註解繼承只針對class 級別註解有效。

(一)改造MyAnnotation

1
2
3
4
5
6
7
8
9
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,
    ElementType.PARAMETER, ElementType.CONSTRUCTOR,
    ElementType.LOCAL_VARIABLE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
    String name() default "Jack";
    int age() default 20;
}

(二)繼承類及使用自定義註解

1
2
3
4
@MyAnnotation
public class Fruit {
 
}
1
2
3
public class Apple extends Fruit{
     
}

(三)獲得父類的annotaion

1
2
3
4
5
6
7
8
9
public class AnnotationTest2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException {
        Class<Apple> appleClass = (Class<Apple>) Class.forName("chapter10_04.Apple");
        Annotation[] annotations = appleClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}






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