5

我執行註釋處理器,以確保標有註釋的元素是實現某個接口的類的實例,或者是實現某個接口的類的用途:如何使用@Target處理批註(ElementType.TYPE_USE)?

@Documented 
@Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE }) 
@Retention(value = RetentionPolicy.RUNTIME) 
public @interface AuditSubject { 

} 

public interface Auditable { 
    // methods that provide data for writing a log entry... 
} 

public class Report implements Auditable { 

} 

對於註釋元素時,必須在方法執行後創建日誌條目(使用AOP)。示例:

@CreateLogEntry 
public Result persist(@AuditSubject Report newReport) { 
    // A log entry must be created with the incoming newReport.  
} 

@CreateLogEntry 
public UpdateResult<@AuditSubject Report> update(Report update) { 
    // A log entry must be created with the updated report which is not the same instance as 'update' (cannot use it). 
} 

@CreateLogEntry 
public Result persistBatch(List<@AuditSubject Report> batch) { 
    // A log entry must be created for each element in 'batch' after this method execution. 
} 

必須創建日誌條目,前提是該報告實現可審計;如果沒有,運行時異常被拋出(哎呀,我忘了實現該接口!)。因此,註釋處理器有助於在編譯時捕捉程序員的錯誤。到目前爲止,我已經成功地檢查了參數中的所有用途,但不能用於類型用途。從註釋處理器相關的代碼如下:

@Override 
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
    for (Element annotated : roundEnv.getElementsAnnotatedWith(AuditSubject.class)) { 
     // Only prints elements with ElementKind.PARAMETER)! 
     this.messager.printMessage(Kind.NOTE, TextUtils.replaceParams("annotated: {} ; Kind : {} ; enclosing : {}", annotated, annotated.getKind(), annotated.getEnclosingElement())); 

     if (annotated.getKind() == ElementKind.PARAMETER) { 
      // Code here works as expected, raises errors for annotated parameters of classes that don't implement Auditable. 
     } else if (annotated.getKind() == ElementKind.WHAT_TO_USE) { 
      // What ElementKind do I need to use here? 
     } 
    } 

    return false; 
} 

與樣ElementKind.PARAMETER只有註釋元素被識別(在處理的循環(第一行)只打印用於'newReport'單行)如何可以檢查註釋類型實現Auditable?沒有"ElementKind.TYPE_USE"不斷使用。我無法找到關於此事的任何相關信息。感謝您的關注。

回答

4

Java的註釋處理API設計的Java時僅支持聲明的註釋。該API僅支持訪問聲明,如字段,方法和方法參數。它不訪問局部變量聲明,也不訪問方法體內的其他註釋,也不訪問註釋。

如果您希望處理的方法體中類型的註釋或註釋,你需要編寫自己的代碼來調用那些類型或改乘檢查方法中的代碼行。

對此的一個替代方案是使用像Checker Framework的工具。它實現了自己的訪問者,因此在每個類型註釋的出現處都會調用建立在其上的註釋處理器。