2010-06-24 52 views
115

任何人都可以以明確的方式解釋java.lang.annotation.RetentionPolicy常數SOURCECLASS,並且RUNTIME之間的實際差異?不同的保留策略如何影響我的註釋?

我也不太確定什麼短語「保留註釋」的意思。

+4

文檔(http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/RetentionPolicy.html)非常清晰。 – 2010-06-24 07:35:50

+0

是的,我已經閱讀,但我不明白它是如何工作的。事實上,如果我嘗試'這個短語': 「」「」 註解將被編譯器記錄在類文件中,但不需要在運行時由VM保留。「」「」 然後打開一個反編譯的類,我在其中保留CLASS的註釋我沒有發現任何東西... – xdevel2000 2010-06-24 07:48:51

+2

然後你的反編譯器似乎不支持註釋。jd-gui正常工作。 – musiKk 2010-06-24 07:59:24

回答

136
  • RetentionPolicy.SOURCE:在 編譯丟棄。這些註釋不 任何意義編譯已 結束後,所以他們不會被寫入 字節碼。
    示例:@Override@SuppressWarnings

  • RetentionPolicy.CLASS:在 類負載丟棄。做 字節級的後期處理時很有用。 出人意料的是,這是 默認。

  • RetentionPolicy.RUNTIME:不要 丟棄。註釋應該可以運行時用於反映 。 例子:@Deprecated

來源: 舊的URL是現在死了 hunter_meta hunter-meta-2-098036取代。如果發生這種情況,我正在上傳頁面的圖像。

Image(點擊右鍵,選擇「在新標籤/窗口打開圖片」) enter image description here

+1

感謝您的報價,這裏最有趣的是'RetentionPolicy.CLASS'的使用案例 – Max 2013-02-12 10:22:29

+1

你能解釋爲什麼RetentionPolicy.class是有趣/令人驚訝的默認? – sudocoder 2015-01-12 21:33:59

+1

@sudocoder - 請參考這些鏈接:http://stackoverflow.com/a/5971247/373861和http://stackoverflow.com/a/3849602/373861。我相信這個特殊的策略是字節碼測試所必需的。雖然我從來沒有用過它 – Favonius 2015-01-15 06:56:00

34

根據你對類反編譯的意見,這裏是如何,我認爲它應該工作:

  • RetentionPolicy.SOURCE:不會出現在反編譯類

  • RetentionPolicy.CLASS:出現在反編譯的類,但是不能在運行時被檢查與反射與getAnnotations()

  • RetentionPolicy.RUNTIME:出現在反編譯的類,並且可以在運行時與getAnnotations()

+0

是的,我也這麼認爲,但是在反編譯的類中沒有任何東西存在! !因此我很困惑...我會嘗試使用javap工具檢查類文件 – xdevel2000 2010-06-24 08:00:55

+0

javap返回什麼地方,然後放? – xdevel2000 2010-06-24 08:07:36

+0

短而甜,正是我在找的東西。 – Matt 2017-05-31 13:30:26

13

被檢查與反射最小的可運行例子

語言水平

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.SOURCE) 
@interface RetentionSource {} 

@Retention(RetentionPolicy.CLASS) 
@interface RetentionClass {} 

@Retention(RetentionPolicy.RUNTIME) 
@interface RetentionRuntime {} 

public static void main(String[] args) { 
    @RetentionSource 
    class B {} 
    assert B.class.getAnnotations().length == 0; 

    @RetentionClass 
    class C {} 
    assert C.class.getAnnotations().length == 0; 

    @RetentionRuntime 
    class D {} 
    assert D.class.getAnnotations().length == 1; 
} 

字節碼級:使用javap我們觀察到Retention.CLASS註解類獲取一個RuntimeInvisible類屬性:

#14 = Utf8    LRetentionClass; 
[...] 
RuntimeInvisibleAnnotations: 
    0: #14() 

Retention.RUNTIME註釋獲得一個RuntimeVisible類屬性:

#14 = Utf8    LRetentionRuntime; 
[...] 
RuntimeVisibleAnnotations: 
    0: #14() 

Runtime.SOURCE註釋.class沒有得到任何註釋。

Examples on GitHub給你玩。

7

保留策略:保留策略決定註釋在什麼時候被丟棄。

1.SOURCE: annotation retained only in the source file and is discarded 
      during compilation. 
2.CLASS: annotation stored in the .class file during compilation, 
     not available in the run time. 
3.RUNTIME: annotation stored in the .class file and available in the run time. 

保留策略是使用Java的內置註釋指定的:@Retention。

0

RetentionPolicy.SOURCE:該註釋將在程序的源代碼中可用,它既不在.class文件中,也不在運行時可用。由編譯器使用。
RetentionPolicy.CLASS:註釋將位於.class文件中,但它在運行時不可用。由字節代碼操作工具(如ASM)使用,執行修改
RetentionPolicy.RUNTIME:該註釋將在.class文件和運行時提供,用於通過getAnnotations()的java反射進行檢查。

相關問題