そらとぶへび

仕事・プライベートを通しての気づき、JavaやPHP、データベースやサーバの話などこつこつと書いていきます

アノテーションの基礎

アノテーションとは、プログラムの構成要素に付与するメタ情報で、修飾子の一つとして機能する。Java SE 5 から導入された機能であり、 @Xxxxxx の形式で、Java の言語機能で表現できない補足情報を注釈 (annotation) として記述するための仕組み。アノテーションコンパイラや解析ツール、もしくはフレームワークによって処理される。

アノテーション適用可能なプログラム要素

  • 型宣言
  • フィールド変数宣言
  • メソッド宣言
  • パラメータ変数宣言
  • コンストラクタ宣言
  • ローカル変数宣言
  • アノテーション型宣言
  • パッケージ宣言

アノテーションの役割

アノテーションの主な役割として「構文補助」と「宣言的プログラミング」がある。

  • 構文補助

 @Overrideなどが構文補助にあたり、活用することでJavaの文法の独自拡張に近いことができる。

  • 宣言的プログラミング

 プログラムを機能や役割で部品に分解し、形式的に記述する。ツールやフレームワークで解析することで、部品の間をつなぐコードを自動生成することができる。

標準アノテーション

Javaの標準ライブラリでで提供されているアノテーションのことを、標準アノテーションと呼ぶ。

アノテーション 説明
@Override   オーバライドしたメソッドであることを明示
@Deprecated  非推奨メソッドであることを宣言
@SuppressWarnings  警告メッセージを抑制

アノテーション型の宣言

アノテーションは型の一種であり、他の型同様に独自で作成することができる。
@interfaceが指定されているクラスは、暗黙的にjava.lang.annotation.Annotationインタフェースの継承クラスになる。

アノテーション型の宣言の文法

[修飾子] @interface Annotation名{
    キーの型 キーの名前(); // アノテーション要素
    ...
}

// アノテーション要素のある例
public @interface SuppressWarnings {
  String value();
}
// enumを利用したアノテーション要素のある例
public enum eType {AAA, BBB, CCC}
@interface EnumAnnotation {
  eType value();
}

//複数のアノテーション要素のある例
public @interface MyAnnotation {
  String foo();
  int bar();
  class cls();
  String[] qux();
}


//デフォルト値を指定した複数のアノテーション要素のある例
public @interface MyAnnotation {
  String foo() default "aaa";
  int bar();
  class cls();
  String[] qux();
}

アノテーション要素の型は次に限定される。

  • 基本型
  • String型
  • enum
  • アノテーション
  • Class型
  • 上記を要素とする配列型(配列の配列は不可)

アノテーション要素のないアノテーションをマーカーアノテーションと呼ぶ。(@Overrideなど)


また、アノテーションの宣言は、抽象メソッド宣言と比較して次の制約がある。

  • 引数は持てない。
  • throws節が持てない。
  • ジェネリックメソッドが使えない。

メタアノテーション

アノテーションを独自で作成する際に使用するアノテーションをメタアノテーションと呼ぶ。
あらかじめ用意されている標準メタアノテーション型は次のものがある。

アノテーション名  説明
@Target   アノテーションが、どの要素に利用できるものかを宣言する
@Retention  アノテーションの存在期間を宣言する
@Documented  アノテーションjavadocによる文書化の対象とする
@Ingerited   アノテーションが独自に継承されることを宣言する。
@Repeatable  同じ対象要素に同じアノテーションを複数指定可能(java8以降)
Target アノテーション

アノテーションがどの要素(クラスやメソッドなど)に対して適用することができるかを定義する。指定する要素は enum 型の java.lang.annotation.ElementType で定義される。


値 説明

TYPE クラス・インタフェース・enumアノテーションの宣言
FIELD フィールドの宣言(enum定数を含む)
METHOD メソッドの宣言
PARAMETER メソッドのパラメータの宣言
CONSTRUCTOR コンストラクタの宣言
LOCAL_VALIABLE ローカル変数の宣言
ANNOTATION_TYPE アノテーション型の宣言
PACKAGE パッケージの宣言
Retention アノテーション

アノテーションで付加された情報がどの段階まで保持されるかを定義する。指定する段階は enum 型の java.lang.annotation.RetentionPolicy で定義される。

説明
SOURCE ソース上だけのアノテーションで、クラスファイルには記録されない。
CLASS クラスファイルにもアノテーションの情報が記録される。実行時にはロードされない。Retention アノテーションを指定しなかった場合、CLASS がデフォルトで定義される。
RUNTIME クラスファイルに情報が記録され、さらに実行時にも情報がロードされる。JavaプログラムからリフレクションAPIを利用してアノテーションの情報を読み取るためには、この種別が必要。
Documented アノテーション

対象となるアノテーションにより付加した情報が javadoc コマンドなどで作成したドキュメントに反映されなければならないことを示す。Documented アノテーションはマーカーアノテーションであり、要素は持たない。どのようにドキュメントに反映されるかは、ドキュメントを生成するプログラムの実装に依存する。

Inherited アノテーション

クラス宣言に付加するアノテーションが、対象となるクラスのサブクラスにも継承されることを指示する。

アノテーションの適用

基本的には「アノテーション要素名 = アノテーション要素値」を記述する。
要素が配列の場合は中括弧{}で値を指定する。
なお、アノテーション要素名がvalueのときのみ「value=」は省略できる。

 @MyAnnotation(foo = "abc", bar = 1,cls = String.class, qux = {"aaa","bbb"})
 public String exec(String str){
   ・・・