さまざまな保持ポリシーが注釈にどのように影響しますか?


175

誰もが明確な方法で説明することができます間の実用的な違いjava.lang.annotation.RetentionPolicy定数SOURCECLASSおよびRUNTIME

また、「注釈を保持する」というフレーズの意味がよくわかりません。


5
ドキュメント(java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/…)は非常に明確です。
トゥルーソフト

はい、私はすでに読みましたが、実際にはそれがどのように機能するか理解していません。実際、「このフレーズ」を試した場合: "" ""注釈はコンパイラによってクラスファイルに記録されますが、実行時にVMによって保持される必要はありません。"" "から、逆コンパイルされたクラスを開いて、保持ポリシーCLASSの注釈を付けましたが、何も見つかりません...
xdevel2000

2
あなたの逆コンパイラは注釈をサポートしていないようです。jd-guiは正常に動作します。
musiKk 2010年

問題の原因は、デコンパイラーのdjとjadでした。jd-guiで見せてください。
xdevel2000

回答:


209
  • RetentionPolicy.SOURCE:コンパイル中に破棄します。これらの注釈は、コンパイルが完了した後は意味をなさないため、バイトコードに書き込まれません。
    例:@Override@SuppressWarnings

  • RetentionPolicy.CLASS:クラスのロード中に破棄します。バイトコードレベルの後処理を行うときに役立ちます。少し意外なことに、これがデフォルトです。

  • RetentionPolicy.RUNTIME: 廃棄禁止。アノテーションは、実行時にリフレクションに使用できる必要があります。例:@Deprecated

出典: 古いURLは現在死んでいます hunter_metahunter-meta-2-098036に置き換えられました。これでも下がる場合はページの画像をアップロードしています。

画像(右クリックして[新しいタブ/ウィンドウで画像を開く]を選択) Oracle Webサイトのスクリーンショット


1
引用のおかげで、ここで最も興味深いのは次の使用例ですRetentionPolicy.CLASS
Max

1
RetentionPolicy.classがなぜ興味深いのか、意外にもデフォルトなのはなぜですか?
sudocoder、2015年

1
@sudocoder-次のリンクを参照してください:stackoverflow.com/a/5971247/373861およびstackoverflow.com/a/3849602/373861。この特定のポリシーは、バイトコードの計測に必要であると思います。自分で使ったことはありませんが。
ファボニウス

最後に、このシリーズの次の記事では、Javaのリフレクション機能がどのように拡張され、実行時に注釈を発見できるようにするか、および注釈処理ツール「apt」を使用してビルド時に注釈を使用できるようにする方法を示します。、この記事はどこにありますか?
Sushant

@Sushant:まあ、それがどこにあるのかよくわかりません:)。けれどもはaptこれを参照廃止されましたdocs.oracle.com/javase/7/docs/technotes/guides/apt/...。リフレクションを使用して注釈を発見するために、インターネット上に複数のチュートリアルがあります。あなたはに見ることで起動することができjava.lang.Class::getAnno*、同様の方法でjava.lang.reflect.Methodjava.lang.reflect.Field
ファボニウス

57

クラスの逆コンパイルについてのあなたのコメントによると、これは私がそれがうまくいくはずだと私が思う方法です:

  • RetentionPolicy.SOURCE:逆コンパイルされたクラスに表示されません

  • RetentionPolicy.CLASS:逆コンパイルされたクラスに表示されますが、次のリフレクションでは実行時に検査できません getAnnotations()

  • RetentionPolicy.RUNTIME:逆コンパイルされたクラスに表示され、実行時にリフレクションを使用して検査できます getAnnotations()


はい、私もそう思いましたが、逆コンパイルされたクラスには何もありません!!! そして私は混乱しています...私はjavapツールでクラスファイルを検査しようとします
xdevel2000

javapはどこに配置されても何も返しませんか?
xdevel2000

1
RetentionPolicy.CLASSの使用例?
Rahul

20

最小限の実行可能な例

言語レベル

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;
}

バイトコードレベル:注釈付きクラスがRuntimeInvisibleクラス属性を取得javapすることを確認します。Retention.CLASS

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

一方、Retention.RUNTIMEアノテーションはRuntimeVisibleクラス属性を取得します。

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

そして、Runtime.SOURCE注釈付き.classは、いかなる注釈も取得しません。

GitHubの例で遊んでください。


それでは、Runtime.SOURCEおよびRuntime.CLASSの用途は何ですか?
Praveen Kamath

@PraveenKamath私はそれらが役に立つ例を知りません。ほとんどの開発者が決して実行しないような低レベルのJVMを実行している場合にのみ発生する可能性があります。それらのためのアプリケーションを見つけたら私に知らせてください。
Ciro Santilli郝海东冠状病六四事件法轮功

5

保持ポリシー:保持ポリシーは、注釈が破棄される時点を決定します。これは、Javaの組み込みアノテーションを使用して指定されます:@Retention[概要]

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.

0
  • CLASS :注釈はコンパイラによってクラスファイルに記録されますが、実行時にVMによって保持される必要はありません。
  • RUNTIME :注釈はコンパイラによってクラスファイルに記録されるべきであり、彼らは反射的読み取ることができるので、実行時にVMによって保持しました。
  • SOURCE :注釈はコンパイラによって破棄されます。

Oracleドキュメント

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.