いまさら聞けない「Javadoc」と「アノテーション」入門【改訂版】Eclipseではじめるプログラミング(22)(3/4 ページ)

» 2011年05月19日 00時00分 公開
[小山博史株式会社ガリレオ]

独自のアノテーション型を作るには

 既存のアノテーション型を使ってアノテーションをソースコードへ埋め込むだけでなく、独自のアノテーションを使いたいときがあります。そんなときは、自分でアノテーション型を定義します。どんな例があるか、考えてみましょう。

コメントで対応しようとすると

 クラスに関する情報として、作成者、バージョン情報、依存するライブラリをソースコードへ埋め込みたかったとします。例えば、コメントで対応しようとすると次のように記述します。

package sample22.app7;
/**
 * Author  koyama
 * Version  1.0
 * Depend on  sample22.lib.Util
 */
public class A {}

Javadocで対応しようとすると

 Javadocコメントを使う場合は、次のようになります。AuthorとVersionに対応するJavadocコメント用のタグとして、@author、@versionがあるので、これを使い、「Depend on:」に対応するものはないので、単なるコメントとして入れておくことになります。

package sample22.app7;
/**
 * Depend on  sample22.lib.Util
 * @author  koyama
 * @version  1.0
 */
public class A {}

 「Depend on:」の情報をソースコードへ記載するに当たって、コメントだと「depend on:」とタイプミスをして記述してしまうこともあります。何らかの方法で正しく入れたい場合には、アノーテションを使います。

アノーテションを使うと

package sample22.app7;
/**
 * @author  koyama
 * @version  1.0
 */
@Dependon("sample22.lib.Util")
public class A {}

 依存するライブラリの情報は「Dependon」というアノテーション型を使って記述することにすれば、タイプミスで@dependonとしてしまった場合にもコンパイラがエラーを出してくれます。このように、ソースコードと一緒に埋め込みたい情報を定義したアノテーション型を独自に用意すると、何かと便利です。

アノテーションで複数の情報を付加

 JavadocコメントとDependonで情報を付加するという方法で十分ですが、Javadocコメントと内容が重複するものの、アノテーションにも全部指定したい場合もあるでしょう。ここからの説明にも都合が良いので、例えば、次のような「ClassInformation」というアノテーションを用意して対応することについて考えてみます。

package sample22.app7;
/**
 * @author koyama
 * @version 1.0
 */
@ClassInformation(
    author = "koyama",
    version = 1.0,
    dependon = "sample22.lib.Util"
)
public class A {}

 このように、アノテーションには、「author」「version」「dependon」といった複数の要素を持たせることもできます。

アノテーション型の定義の作成

 このアノテーションに対応するアノテーション型は次のように定義できます。アノテーションを指定するときは値を代入していますが、アノテーション型の定義ではメソッドを定義する点に注意してください。

 ちなみに、Eclipseでは[ファイル]→[新規]→[注釈]とすることで、アノテーション型定義のひな型を作成できます。

package sample22.app7;
 
public @interface ClassInformation {
    String author();
    double version();
    String dependon();
}

アノテーションで1つの情報を付加

 また、「@Dependon("sample22.lib.Util")」というアノテーションを使うためには、アノテーション型としてDependonを定義する必要があります。こちらは、次のように定義できます。後で理由を説明しますが、1つしか要素を持たない場合は、普通は「value」という要素名を使います。

package sample22.app7;
public @interface Dependon {
    String value();
}

 ここでは、独自アノテーション型が必要になる例を考えてみました。DependonやClassInformationといったアノテーション型を用意したくなることがある点について、理解できたでしょうか。必要性について理解したところで、アノテーション型の定義について、詳細を理解しましょう。

アノテーション型を定義するには

 アノテーション型の定義を見てinterface型の定義に似ていると思った人は多いでしょう。その通りでアノテーション型は、interface型の特殊なものです。入門レベルで知っていればいい範囲で説明します。

 型の定義に当たっては、キーワードintefaceの前に@文字を付け、{ } 内には「アノテーション要素(annotation element)」を宣言します。interfaceが宣言できる場所であれば、アノテーションを宣言できます。修飾子もinterfaceに適用できるものを付けられます。

型の定義

interface修飾子 @interface アノテーション名 {
    アノテーション要素宣言
}

要素(メソッド)の宣言

 アノテーション要素については、次の基本的な宣言を覚えておけば十分です。「default デフォルト値」は省略可能です。型名には、基本データ型Stringenum型、他のアノテーション型、Class、これらの型のどれかの配列型を指定できます。

型名 アノテーション要素名() default デフォルト値;

アノテーション型の5つの特徴

 アノテーション型については、下記のような特徴があります。アノテーションはインターフェイスの特殊なものなので、アノテーション要素は文法的にはメソッドです。ただ、説明上は、アノテーション要素とした方が分かりやすいので、こちらを使います。

  • アノテーション型宣言ではジェネリックは使えない
  • アノテーション型は暗黙のうちにjava.lang.annotation.Annotationを拡張する(他のクラスからextendsできない)
  • アノテーション要素はパラメータを持てない
  • アノテーション要素は型パラメータを持てない
  • アノテーション要素はthrows節を持てない

defaultキーワードでデフォルト値を指定

 なお、defaultキーワードを使って、要素に値が指定されなかったときのデフォルト値を持たせることもできます。次の例では、versionの初期値を1.0としています。デフォルト値には定数式かリテラルを指定できます。ただし、nullは指定できません。

package sample22.app8;
public @interface ClassInformation {
    String author();
    double version() default 1.0;
    String dependon();
}

アノテーション要素の表現を変更

 ここで、アノテーション要素「dependon」の表現を変更してみます。前提として、ほとんどのクラスがsample22.lib.Utilクラスに依存しているとします。その場合は、指定省略により自動でsample22.lib.Utilに依存しているようにしたいはずです。

 また、説明を追加できるようにしたいとします。その場合は、次のような@Dependonを用意します。

@interface Dependon {
    String value() default "sample22.lib.Util";
    String description() default "";
}

 ClassInformationは次のようにします。dependon()について、StringではなくDependonを使っている点に注意してください。

@interface ClassInformation {
    String author();
    double version() default 1.0;
    Dependon dependon();
}

 @Dependonが初期値を持っているので、アノテーションは次のように書くことができます。dependonは、@Dependonで指定されている初期値で初期化できる点に注目してください。

package sample22.app9;
/**
 * @author koyama
 * @version 1.0
 */
@ClassInformation(
    author = "koyama",
    version = 1.0,
    dependon = @Dependon
)
public class A {}

 @Dependonのdescription要素の値を変更したい場合は次のように記載します。

package sample22.app9;
@ClassInformation(
    author = "koyama",
    version = 1.0,
    dependon = @Dependon(description = "メソッドaを使用")
)
public class B {}

 アノテーション型の定義については以上です。 次ページでは、さらにアノテーションの指定方法について説明し、いくつかの特殊なアノテーションにも触れます。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。