保持ポリシーと対象型
SOURCE、CLASS、RUNTIME の保持ポリシーを選び、@Target で適用対象の要素を制限します。
「保持ポリシーと対象型」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
3つの保持ポリシー
SOURCE: コンパイラによって破棄されます(APT でのみ有用です)。CLASS: .class ファイルに書き込まれますが、実行時には利用できません。RUNTIME: リフレクションで利用できます。ほとんどのフレームワークのアノテーションは RUNTIME を使用します。
SOURCE 保持: コンパイル時のみ
SOURCE アノテーションはアノテーションプロセッサによって処理された後、破棄されます。@Override と @SuppressWarnings は SOURCE であり、コンパイラに情報を伝えますが、.class ファイルには含まれません。
@Retention(RetentionPolicy.SOURCE)
public @interface GenerateBuilder {}
// APT generates a Builder class when it sees @GenerateBuilder
// The annotation itself disappears from the compiled outputCLASS 保持: バイトコード解析
CLASS アノテーションは、バイトコード解析ツール(PMD、FindBugs、ASM)向けに .class ファイルへ含められますが、リフレクションを使って実行時に読み取ることはできません。
@Retention(RetentionPolicy.CLASS)
public @interface ThreadSafe {}
// Visible in bytecode, invisible to Class.getAnnotation() at runtimeRUNTIME 保持: リフレクションによる処理
RUNTIME アノテーションは実行時まで保持され、getAnnotation() で読み取ることができます。Spring、JUnit、Jackson、Hibernate は RUNTIME の保持を使用します。
@Retention(RetentionPolicy.RUNTIME)
public @interface Route {
String path();
String method() default "GET";
}
// At runtime:
Route r = handler.getClass().getMethod("handle").getAnnotation(Route.class);
System.out.println(r.path()); // e.g. "/users"@Target: 適用箇所の制限
@Target は ElementType の定数を使って、アノテーションを記述できる場所を制限します。許可されていない要素に適用すると、コンパイル時にエラーになります。
import static java.lang.annotation.ElementType.*;
@Target({METHOD, CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface Measured {}すべての ElementType の値
一覧は次のとおりです。TYPE(クラス・インターフェース・enum)、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE、TYPE_PARAMETER(ジェネリック型パラメータ)、TYPE_USE(あらゆる型の使用箇所)。
// TYPE_USE: annotate any type reference
@NotNull String name;
List<@NonNull String> items;
public @Valid User createUser(@NotNull String name) { ... }TYPE と TYPE_USE
TYPE は、クラス・インターフェース・enum の宣言を対象にします。TYPE_USE(Java 8 以降)は、ジェネリクス、キャスト、extends 節など、型のあらゆる使用箇所を対象にするため、型レベルの null 安全性アノテーションを実現できます。
@Target(ElementType.TYPE_USE)
@interface NonNull {}
// Can be applied to:
List<@NonNull String> list;
@NonNull String result = (@NonNull String) obj;Target と Retention の組み合わせ
実用的なフレームワークアノテーションの多くは、RUNTIME の保持と特定の対象を組み合わせます。たとえば、フィールドだけに適用するバリデーションアノテーションなどです。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Range {
int min() default 0;
int max() default Integer.MAX_VALUE;
}@Inherited によるアノテーションの継承
@Inherited は、クラスレベルのアノテーションをサブクラスに継承させるメタアノテーションです。メソッドやフィールドのアノテーションには効果がありません。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Framework {}
@Framework class Base {}
class Child extends Base {} // @Framework visible on Child too@Documented: Javadoc への含め方
@Documented を付けると、アノテーションを付けた要素の生成された Javadoc に、そのアノテーションが表示されます。付けない場合、アノテーションは API ドキュメントに表示されません。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
String description() default "";
}実行時の保持情報の読み取り
アノテーション型自体の保持情報は、アノテーションのクラスオブジェクトに対して getAnnotation(Retention.class) を使用して調べることができます。
Retention r = Retry.class.getAnnotation(Retention.class);
System.out.println(r.value()); // RUNTIME, CLASS, or SOURCE確認問題
クラス、インターフェース、enum の宣言を対象とする ElementType はどれですか。
まとめ
コンパイル時のツールには SOURCE、バイトコード解析には CLASS、リフレクションを使うフレームワークには RUNTIME を使用します。@Target で使用範囲を制限し、誤用を防ぎます。API 用のアノテーションには @Documented を、クラス階層で継承するアノテーションには @Inherited を追加します。
よくある質問
「保持ポリシーと対象型」レッスンは無料ですか?
はい。「保持ポリシーと対象型」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「保持ポリシーと対象型」で何を学びますか?
SOURCE、CLASS、RUNTIME の保持ポリシーを選び、@Target で適用対象の要素を制限します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「保持ポリシーと対象型」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。