Java基礎ーアノテーション

アノテーション(注釈)

クラス、フィールド、ローカル変数に対して付与することができる。
@Xxx の形式で、Java の言語機能としては表現できない補足情報を注釈 (annotation) として記述するための仕組み。

標準アノテーション

  1. Override
    スーパークラスのメソッドをオーバーライド(明示的)
  2. Deprecated
    クラスやメソッドが非推奨である
  3. SuppressWarnings
    コンパイル時の警告を抑制する
    適用範囲を広くしすぎない(メソッドの前につけるとメソッド全体の警告が抑制されるのでコーディングミスに気づけなくなる)
/**
 * Deprecatedは、バージョンアップによって、ユーザーに使用して欲しくなくなったメソッドに付与するアノテーション。<br>
 * アノテーションの属性「since」にはいつから非推奨なのか、<br>
 * 「forRemoval」には将来消える予定なのかを指定する。<br>
 */
@Deprecated(since = "1.5", forRemoval = true)
public void deprecatedMethod() {
    System.out.println("非推奨のメソッド");

    // @SuppressWarningsはどうしても出てしまう警告を抑制する
    // 属性には理由の定数を記述する
    @SuppressWarnings("unchecked")
    List<String> list = (List<String>) method();
    list.forEach(word -> {
        System.out.println(word);
    });

    // @SuppressWarningsはどうしても出てしまう警告を抑制する
    // 属性には理由の定数を記述する
    @SuppressWarnings("unused")
    String name = "オラフ";
}

アノテーションを自作する

宣言

public @interface Hogehoge {
}

アノテーションの宣言に以下の2つのアノテーションを付ける
Retention
アノテーションの読み込みタイミングを指定する。

設定値 説明
CLASS コンパイル時にクラスファイルに記録される。実行時にVMに読み込まれない
RUNTIME 実行時にVMに読み込まれる
SOURCE コンパイル時に破棄

Target
注釈型が適用可能なプログラム要素を指定する。

設定値 説明
ANNOTATION_TYPE アノテーションに適用可
CONSTRUCTOR コンストラクタに適用可
FIELD フィールドに適用可
LOCAL_VARIABLE ローカル変数に適用可
METHOD メソッドに適用可
PACKAGE パッケージに適用可
PARAMETER 引数に適用可
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Hogehoge {
}

属性値を設定するとアノテーション記述時に値を渡せるようになる。
属性値に設定できるのは、基本クラスとその配列のみ。
属性値の後ろにdefaultと書くことでデフォルト値を指定可能。
デフォルト値がない属性はアノテーション使用時に値を指定することを強制される。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Hogehoge {

    /** 属性値。 */
    String value();

    boolean canUse() default false;
}

アノテーション使用例
属性値を指定するときに、valueのみ指定する場合は属性値を省略できる。

@Hogehoge("abcde")
void sampleMethod() {
    try {
        Method method = this.getClass().getDeclaredMethod("sampleMethod");
        Hogehoge hogehoge = method.getAnnotation(Hogehoge.class);
        System.out.println(hogehoge.value()); // abcde
    } catch (NoSuchMethodException | SecurityException e) {
        e.printStackTrace();
    }
}