Javaのプログラムを見てみると「@xxx」のような形で記述されているコードを見かけることがあると思います。
これは「アノテーション」と呼ばれるJavaのコードに対する「注釈」の役割を果たす記述方法です。
本記事では、アノテーションの仕組みと基本的な使い方を解説していきたいと思います。
アノテーションを理解するにはJavadocの知識が大事!
アノテーションについての説明に入る前に、アノテーションを理解する上で欠かせない「Javadoc」のご紹介を少しさせてもらいたいと思います。
Javadocとは
JavadocはJavaプログラムのソースコード上にコメントを書き込むために利用されます。
Javadocを利用することで、「プログラムコード用ファイル」と「プログラムの説明用ファイル」に分ける必要がなくなり、ファイル1つで実際に動作させるプログラムコードと説明文の両方を管理することが可能となります。
Javadocを利用するとどんなメリットがあるの?
Javadocを利用するとコードと仕様書を分けて管理する必要がなくなる大きなメリットがあります。
Javadocはソースコード上にコメントを書き込むことが出来るとご紹介しましたが、記述したコメントを別ドキュメントとして生成することも可能で、きちんと情報を記述しておけばJavadocだけでも十分に仕様書として活用することが可能となります。
ソースコードとドキュメントを別々に管理していると、多くのプロジェクトで実際のソースコードとドキュメントの整合性が合わない場面が出てきています。
ソースコードを改修した際、ドキュメントの更新を忘れてしまうことが原因で結局ドキュメントの意味がほとんどなくなってしまっているプロジェクトも少なくありません。
しかし、Javadocを利用することでソースコードを改修した際に同一ファイルのJavadocコメントを編集するだけで良くなることから、ドキュメントの更新忘れが大きく減らせるメリットとなります。
Javaアノテーションとは
アノテーションは英語で「注釈・注記」という意味の言葉です。
Javaのソースコード上でも、重要な情報を記述する際にプログラマ個人の記述方法に頼らず統一した記述法を用いるためにアノテーションが利用されます。
また、アノテーションを記述することでプログラム環境を制御するために利用することも可能です。
プログラマー間で統一した記述法を用いるためのアノテーション
まずJavadoc内で記述するタグとして頻繁に利用されるアノテーションをご紹介していきます。
アノテーション「author」
「author」は「編集者」を表すアノテーションとして頻繁に利用されます。
/** * @author potepanAuthor */
アノテーション「version」
「version」は「クラスやメソッドのバージョン」を表すアノテーションとして「author」とセットで利用されることが多いアノテーションです。
/** * @version 1.03 */
アノテーション「param」
「param」は「引数」を表すアノテーションで引数に対する説明文と一緒に記述されることが多くなっています。
/** * @param name ユーザーの名前 */
アノテーション「return」
「return」は「返り値」を表すアノテーションで処理の後に返却される値の説明を記述します。
/** * @return ユーザーの年齢 */
プログラム環境を制御するためのアノテーション
プログラム制御用として頻繁に利用する標準アノテーションを「Override」をご紹介していきたいと思います。
アノテーション「Override」
「Override」は親クラスのメソッドをサブクラスで定義し直し、動作させることを注釈として表したもので、親クラスに定義されていないメソッドを定義した場合にはエラーとなります。
実際のサンプルコードで確認してみましょう。
@Overrideを付与しなかった場合
public class Main { public static void main(String[] args) { Sample2 sample = new Sample2("ポテパン"); sample.execute(); } } class Sample1 { public String name1; public Sample1(String str) { this.name1 = str; } public void execute() { System.out.println("指定した名前は " + this.name1 + "です。"); } } class Sample2 extends Sample1 { public Sample2(String str) { super(str); } @Override ※1つ目の結果はこの部分のアノテーションを削除してコンパイルしています。 public void execute2() { System.out.println("出力内容を変更しています " + this.name1 + "です。"); } }
まずはアノテーションの「@Override」を付与せずに実行した結果が下記となります。
指定した名前は ポテパンです。
サブクラスの「Sample2」には「execute」メソッドは定義されていないため、アノテーションを付与していない場合、親クラスで定義された「execute」メソッドが実行されているのがわかります。
@Overrideを付与した場合(コンパイルエラー)
次に、「execute2」メソッドにアノテーション「@Override」を付与してコンパイルした結果が下記の通りとなります。
Main.java:26: エラー: メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません @Override ^ エラー1個
エラーが起きたのはアノテーションを付与した「execute2」メソッドが親クラスで定義されていないため、コンパイル時のチェックによりエラーとなりました。
アノテーションは付与しなくてもプログラムを動かすことは可能ですが、今回のように本当はサブクラスで定義した「execute」メソッドを利用したいのに親メソッドを実行してしまうようなケースがないよう、コンパイル時に意図しない動作を防ぐことが出来るため、なるべくアノテーションを付与していくことをお勧めします。
@Overrideを付与して正しいコードに修正
では最後にアノテーション「@Override」を付けた状態でサブクラスの「execute」メソッドを実行してみましょう。
Sample2クラスの「execute2」メソッドを「execute」に書き換えたのが下記のコードです。
public class Main { public static void main(String[] args) { Sample2 sample = new Sample2("ポテパン"); sample.execute(); } } class Sample1 { public String name1; public Sample1(String str) { this.name1 = str; } public void execute() { System.out.println("指定した名前は " + this.name1 + "です。"); } } class Sample2 extends Sample1 { public Sample2(String str) { super(str); } @Override // 親クラスで定義されているexecuteに書き換えました public void execute() { System.out.println("出力内容を変更しています " + this.name1 + "です。"); } }
サンプルコードをコンパイルして実行した結果が下記の通りとなります。
出力内容を変更しています ポテパンです。
サブクラスで定義した「execute」メソッドが実行されていることがご確認頂けます。
さいごに:Javaプログラムにおいてアノテーションは必須ではないが利用することで可読性があがる
本記事では、Javaプログラムにおけるアノテーションの仕組みと基本的な使い方についてご紹介してきました。
チーム作業などで記述方法を統一するためのコメント用アノテーションやプログラム制御用アノテーションなど、ご紹介しているのはほんの一部でまだまだ様々なアノテーションが利用出来ます。
アノテーションを利用することで単純なタイプミスや予期せぬ動作を防ぐことが可能となりますので、ぜひ積極的に利用してみましょう。
ドキュメントの更新忘れが無くなることもJavadocを活用する大きなメリットです。