2013-06-21 206 views
9

我想創建自己的註釋來註釋某些局部變量。編寫註釋不是問題,問題是在運行時獲取它們的信息。我只能從註釋的方法或方法參數中獲取一些信息,但不能從局部變量中獲取信息。有什麼辦法可以得到它嗎?ElementType.LOCAL_VARIABLE註釋類型

我自己的註釋是這樣的事情:

public void m(int a) 
@MyOwnAnnotation(some information) 
int b = 5; 
} 

或者,作爲替代,有沒有什麼辦法讓該方法的代碼,來進一步分析它,並最終得到註釋值?

在此先感謝。

+0

您在另一條評論中的鏈接爲您提供了答案:它不受類文件格式的支持。如果您願意,我可以給出與JVM規範和解釋的鏈接的答案,但我認爲其他問題幾乎涵蓋了它。我很驚訝'apt'不能給你你需要的東西。 – parsifal

回答

15

有了反射,你不能檢索局部變量。所以你不能通過反射來檢索局部變量的註釋。我認爲這種註釋只用於編譯器警告。

你可以看http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html

局部變量的註釋並不在類文件中保留(或在運行時),無論在註釋類型設置保留策略。參見JLS 9.6.1.2。

如果您不想檢索方法代碼,可以使用JavaParser(http://javaparser.org/)。

2

JLS 9.6.1.2確實聲明不保留局部變量註釋。但是,JSR 308正在通過社區流程進行。它應該給你你需要的能力。

如果您需要臨時解決方案,請撥打here is an implementation of JSR 308

8

從Java 8開始,局部變量註釋保留在類文件中。正如Erick Hagstrom所指出的,JSR 308修復了這個長期存在的bug,該JSR 308還爲Java語言添加了類型註釋。

但是,Java的反射API尚未更新以在方法體內提供訪問權限。您將需要自己分析類文件。您可以使用諸如ASM之類的工具。我不推薦JavaParser,因爲它沒有在Java 1.5之外更新。

+0

[JLS 9.6.4.2。 @Retention](https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.6.4.2)說了一些不同的東西:_「[...]一個Java編譯器必須確保''a''在出現'a'的類或接口的二進制表示中表示,除非'm'註釋局部變量聲明,否則局部變量聲明的註釋從不保留在二進制表示中。 _ –

-3

目前,正如其他一些文章中提到的,您無法僅從單獨的註釋中檢索局部變量值。

但是,我確實有一個類似的問題,並設法使用字段提出解決方案。樣本代碼如下:

接口類

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface test{ 
} 

POJO

public class testObject{ 
    @test 
    private String one; 
    private String two; 

    //Getters and Setters 
} 

獲取對象值

public void getFields (Object obj){ 
    Field fields = obj.getClass().getDeclaredFields(); 

    for (Field f : fields){ 
     test fieldAnnotation = f.getAnnotation(test.Class); 
     if (fieldAnnotation != null){ 
      f.get(obj); 
      // Do things here based on the values 
     } 
    } 
} 

主類

public static void main(String[] args){ 
    //Create object 
    testObject test = new testObject(); 

    test.setOne("testOne"); 
    test.setTwo("testTwo"); 
    getFields(test); 
} 

希望這有助於解釋你如何能得到的字段基於註解的對象。您只需使用註釋來標記要檢索的字段,然後從對象中讀取值。