web-dev-qa-db-ja.com

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

誰でもJava.lang.annotation.RetentionPolicy定数SOURCECLASS、およびRUNTIME

「注釈を保持する」というフレーズの意味も正確にはわかりません。

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

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

  • RetentionPolicy.RUNTIME: 廃棄禁止。注釈は、実行時に反映する必要があります。例:@Deprecated

出典:古いURLは現在無効です hunter_meta hunter-meta-2-098036 に置き換えられます。これがダウンした場合でも、ページの画像をアップロードしています。

画像 (右クリックして「新しいタブ/ウィンドウで画像を開く」を選択)Screenshot of Oracle website

192
Favonius

クラスの逆コンパイルについてのあなたのコメントによると、これは私がそれがどのように機能するべきだと思うかです:

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

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

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

49
ewernli

最小限の実行可能な例

言語レベル

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は注釈を取得しません。

GitHubの例 一緒に遊ぶ。

_RetentionPolicy.SOURCE_:注釈はプログラムのソースコードで使用できますが、.classファイルでも実行時でも使用できません。コンパイラーによって使用されます。
_RetentionPolicy.CLASS_:注釈は.classファイルにありますが、実行時には使用できません。 ASMなどのバイトコード操作ツールで使用され、変更を実行します
_RetentionPolicy.RUNTIME_:注釈は、.classファイルとランタイムで、getAnnotations()を介したJavaリフレクションによる検査で利用可能になります。

4
yoAlex5

保持ポリシー:保持ポリシーは、注釈が破棄される時点を決定します。

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を使用して指定されます。

3
wahid_cse