既存のアノテーション型を使ってアノテーションをソースコードへ埋め込むだけでなく、独自のアノテーションを使いたいときがあります。そんなときは、自分でアノテーション型を定義します。どんな例があるか、考えてみましょう。
クラスに関する情報として、作成者、バージョン情報、依存するライブラリをソースコードへ埋め込みたかったとします。例えば、コメントで対応しようとすると次のように記述します。
package sample22.app7; /** * Author koyama * Version 1.0 * Depend on sample22.lib.Util */ public class A {}
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(); }
また、「@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 デフォルト値」は省略可能です。型名には、基本データ型、String、enum型、他のアノテーション型、Class、これらの型のどれかの配列型を指定できます。
型名 アノテーション要素名() 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.