Java注解(2)注解的使用:編譯時和運行時處理


目錄:
1.注解的編譯時處理
2.注解的運行時處理

上一篇學到注解的基本概念以及如何定義注解。
接下來學習如何提取注解(拿到注解的內容)並使用注解.

1.編譯時處理:

原理:APT技術
處理對象:@Retention=Source的注解
編譯時處理需要使用到APT技術,該技術提供了一套編譯期的注解處理流程。

在編譯期掃描.java文件的注解,並傳遞到注解處理器,注解處理器可根據注解生成新的.java文件,這些新的.java問和原來的.java一起被javac編譯。

這里需要引入注解處理器這個概念,注解處理器是一個在javac編譯期處理注解的工具,你可以創建注解處理器並注冊,在編譯期你創建的處理器以Java代碼作為輸入,生成文件.java文件作為輸出。
注意:注解處理器不能修改已經存在的Java類(即不能向已有的類中添加方法)。只能生成新的Java類。

2.運行時處理

原理: 通過反射機制獲取注解。
處理對象:@Retention=RUNTIME的注解

2.1判斷某個注解是否存在於Class、Field、Method或Constructor:

Class.isAnnotationPresent(Class)
Field.isAnnotationPresent(Class)
Method.isAnnotationPresent(Class)
Constructor.isAnnotationPresent(Class)

例如:判斷某個注解是否存在於Class

Class cls = Person.class;
if (cls.isAnnotationPresent(Report.class)) {
    Report report = cls.getAnnotation(Report.class);
    ...
}

判斷某個注解是否存在於Field、Method或Constructor中與Class類似。
2.2直接從Class、Field、Method或Constructor讀取到Annotation:

Class.getAnnotation(Class)
Field.getAnnotation(Class)
Method.getAnnotation(Class)
Constructor.getAnnotation(Class)

例如直接從Class中讀取Annotation:

Class cls = Person.class;
Report report = cls.getAnnotation(Report.class);
if (report != null) {
   ...
}

直接從Field、Method或Constructor中與從Class中讀取類似。

2.3讀取方法參數的Annotation
比從Class、Field、Method或Constructor讀取麻煩一點。
因為方法參數本身可以看成一個數組,而每個參數又可以定義多個注解,所以,一次獲取方法參數的所有注解就必須用一個二維數組來表示。例如,對於以下方法定義的注解:

public void hello(@NotNull @Range(max=5) String name, @NotNull String prefix) {
}

要讀取方法參數的注解,我們先用反射獲取Method實例,然后讀取方法參數的所有注解:

// 獲取Method實例:
Method m = ...
// 獲取所有參數的Annotation:
Annotation[][] annos = m.getParameterAnnotations();
// 第一個參數(索引為0)的所有Annotation:
Annotation[] annosOfName = annos[0];
for (Annotation anno : annosOfName) {
    if (anno instanceof Range) { // @Range注解
        Range r = (Range) anno;
    }
    if (anno instanceof NotNull) { // @NotNull注解
        NotNull n = (NotNull) anno;
    }
}

讀取到注解后,就可以進行實際的業務代碼處理了。

運行時處理注解的缺點:
1:通過反射會影響運行效率
2:如果注解無法保存到運行時的話,是無法使用運行時處理的

參考:
編譯時處理參考
APT技術
運行時注解處理參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM