【Java入門】アノテーションの使い方と作成する方法

継承したクラスのメソッドなどで「@Override」なんて記述をみたことはありませんか?

このような記述はアノテーションと呼ばれ、これを記述した場合その場所では指定した規則に従う必要があるので、例えばスペルミスやバグの発生を防止することになり便利なんです。

この記事では、アノテーションについて以下の内容で解説していきます。

  • アノテーションとは
  • アノテーションの使い方
  • 独自のアノテーションを作成する方法

今回はアノテーションについて、使い方をわかりやすく解説します!

なお、Javaの記事については、こちらにまとめています。

目次

アノテーションとは

アノテーションとは元々、注釈、注記といった意味を表す英語です。

プログラミング用語でも、注意書きを追加する機能になり余白に文字を追加する機能です。アノテーションはテータの有無、データの数によって3種類に分かれます。

  • 名前だけでデータのないマーカー 例:@Override、@Deprecated
  • データをひとつ持つ単一アノテーション 例:@SuppressWarnings
  • 複数のデータをもつフルアノテーション

よく使うアノテーションについても解説しておきます。

なお以下の3つのアノテーションについては、後半に使い方を解説したコードを載せているので、そちらもあわせて確認してくださいね。

@Override

記述するメソッドが親クラスのメソッドをオーバーライドしていることを明示します。

このアノテーションによって、親クラスにないメソッドを記述するとエラーが発生しますので、メソッドの名の誤記などを防止することができます

@Deprecated

記述するメソッドの仕様が非推奨であることを明示します。

Javaのバージョンが新しくなって以前の記述では非推奨となるけれども、以前の記述のまま残しておきたい場合などに使用するとよいでしょう。

@SuppressWarning

引数にメッセージを指定することで、記述するメソッドによる警告を非表示にすることができます。

多少の無理があっても実行したい場合などに使用するとよいでしょう。

その他のアノテーション

これらとは別に、独自のアノテーションを定義するために用意されているメタアノテーションと呼ばれているものがあります。

・@Target
独自に定義したアノテーションが何を対象としているか宣言するために使われます。
クラスに対してつけるのか、メソッドにつけるのか、変数につけるのかなどをこれを使って決めます。
例えば@Overrideアノテーションはメソッドに対して、@SuppressWarningアノテーションはほとんどのものに対してつけることができます。

・@Retention
コンパイル時やプログラム実行時にアノテーションの情報を保持するかどうかを決めるために使われます。

この他にも、ドキュメント作成時に便利なJavadocに関連するアノテーションがあります。

・@author 作成者の名前を記述

・@param 引数と引数の説明を記述

・@return 戻り値の説明を記述

・@exception メソッドが投げる例外クラスとその説明を記述

・@version クラスやメソッドなどのバージョンを記述

・@see 他の関連するクラスやメソッドなどの参照先を記述

アノテーションの使い方

それでは、それぞれのアノテーションの使い方についてサンプルコードで確認していきましょう。

@Overrideの使い方

@Overrideの使い方をみていきましょう。

interface InterfaceSample{
	void method01();
}

class ClassSample implements InterfaceSample{
	@Override
	public void method1() {
		System.out.println("method1メソッドを実行しました");
	}
	@Override
	public void method01() {
		System.out.println("method01メソッドを実行しました");
	}
}

public class Main {

	public static void main(String[] args) {
		ClassSample cs = new ClassSample();
		cs.method1();
		cs.method01();
	}

}

method1メソッドに@Overrideアノテーションを付けた実行結果:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	型 ClassSample のメソッド method1() はスーパータイプ・メソッドをオーバーライドまたは実装する必要があります

	at ClassSample.method1(Main.java:7)
	at Main.main(Main.java:20)

method1メソッドの@Overrideアノテーションを除去した実行結果:

method1メソッドを実行しました
method01メソッドを実行しました

この例ではInterfaceSampleインターフェースをClassSampleクラスで実装し、method01メソッドの処理内容をオーバーライドで定義しています。

@Overrideアノテーションをmethod01メソッドには付けていますが、method1と誤記して@Overrideアノテーションを付けるとコンパイルエラーが発生しています。

method1の@Overrideアノテーションを除去するとコンパイルエラーは発生せず実行することは可能です。

この例のようにオーバーライド時のメソッドの記述に誤記があるとコンパイルエラーが発生するので、誤記による別メソッド作成の防止となります。

@Deprecatedの使い方

@Deprecatedの使い方をみていきましょう。

class ClassSample{
	private int num = 0;
	public ClassSample(int num){
		this.num = num;
	}
	@Deprecated
	public int get_num(){
		return num;
	}
	public int getNum(){
		return num;
	}
}

public class Main {

	public static void main(String[] args) {

		ClassSample cs = new ClassSample(1);
		System.out.println("numは " + cs.get_num() + "です");
		System.out.println("numは " + cs.getNum() + "です");

	}

}

実行結果:

numは 1です
numは 1です

この例ではClassSampleクラスのget_numメソッドをgetNumメソッドにメソッド名を変更しています。

旧のget_numメソッドに@Deprecatedアノテーションを付けることで、非推奨の警告が出ますが旧のメソッドを削除することなく使用することも出来ています。

@SuppressWarningsの使い方

@SuppressWarningsの使い方をみていきましょう。

@SuppressWarningsアノテーションは”static-access”や”unused”などの引数を指定して使用します。

class ClassSample{
	private static int num = 0;
	@SuppressWarnings("static-access")
	public ClassSample(int num){
		this.num = num;
	}

	public static int getNum(){
		return num;
	}
}

public class Main {

	@SuppressWarnings("static-access")
	public static void main(String[] args) {

		int num1 = 1;
		@SuppressWarnings("unused")
		int num2 = 1;

		ClassSample cs1 = new ClassSample(num1);
		@SuppressWarnings("unused")
		ClassSample cs2 = new ClassSample(num1);

		System.out.println("numは " + cs1.getNum() + "です");
		System.out.println("numは " + ClassSample.getNum() + "です");
	}

}

実行結果:

numは 1です
numは 1です

この例ではMainクラスでClassSampleクラスをインスタンスを生成せずに使用しているので、ClassSampleクラスではstatic変数とstaticメソッドを宣言しています。

ClassSampleクラスのコンストラクタでstatic変数に値を代入をしますが、代入先をthisで宣言をしているため@SuppressWarnings(“static-access”)アノテーションを付けてstatic変数にアクセスするときの警告を出さないようにしています。

またMainクラスではClassSampleクラスをインスタンス化しても使用していますので、mainメソッドに@SuppressWarnings(“static-access”)アノテーションを付けています。

Mainでは使用していない変数num2とインスタンスcs2に@SuppressWarnings(“unused”)アノテーションを付け、変数を使用していないという警告が発生しないようにしています。

これにより途中まで記述してコンパイルしたい時などに警告を出す出さないを選択できるので便利です。

独自のアノテーションを作成する方法

独自のアノテーションを自作する場合、java.lang.Annotationインターフェースを継承して作成します。

なお、独自のアノテーションの定義は専用のjavaファイルを作成する必要があります。

それでは、サンプルコードを使って自作する方法を確認していきましょう。

AnnotationSample.java:

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import java.lang.annotation.Target;

/*
 * 独自のアノテーションサンプル
 * @auther T.Chouno
 * @version 0.1
 *
 */

@java.lang.annotation.Retention(RUNTIME)
@Target({TYPE,FIELD,CONSTRUCTOR,METHOD})
public @interface AnnotationSample {
	String value();
}

Main.java:

/**
 * Annotationテスト用クラス
 */
@AnnotationSample("ClassSample class")
class ClassSample{
	/**
	 * メンバ変数
	 */
	@AnnotationSample("num field")
	private int num = 0;

	/**
	 * コンストラクタ(メンバ変数のsetter)
	 * @param num メンバ変数
	 */
	@AnnotationSample("constractor")
	public ClassSample(int num){
		this.num = num;
	}

	/**
	 * メンバ変数のgetter
	 * @return num メンバ変数
	 */
	@AnnotationSample("getNum method")
	public int getNum(){
		return num;
	}
}

@AnnotationSample("Main class")
public class Main {

	@AnnotationSample("main method")
	public static void main(String[] args) {

		ClassSample cs = new ClassSample(1);
		System.out.println("numは " + cs.getNum() + "です");

	}

}

実行結果:

numは 1です

この例ではAnnotationSample.javaファイルで独自のアノテーションを作成しています。

@Retentionアノテーションで、RUNTIMEを指定しています。RUNTIMEの他にも、CLASSとSOURCEを指定できます。

RUNTIMEを指定した場合はクラスファイルに記録され実行時に参照できます。CLASSを指定した場合はクラスファイルに記録はされますが、実行時には保持されません。

@Retentionアノテーションを省略した場合は、デフォルトでCLASSが指定されていることになります。SOURCEを指定した場合はアノテーションの情報はソースコード上のみで保持され、コンパイル時に破棄されます。

また、@Targetアノテーションでクラスと変数、コンストラクタ、メソッドにアノテーションを付けるように設定しています。

したがってMain.javaファイルのClassSampleクラス、変数num、ClassSampleコンストラクタ、getNumメソッド、およびMainクラス、mainメソッドに@AnnotationSampleアノテーションを付加することが出来ています。

アノテーションは次のように定義します。

「@interface」句でアノテーションであることを宣言します。

<publicなどの修飾詞> @interface アノテーション名 { }

アノテーション名はアノテーション名.javaと同じにする必要があります。

なお、AnnotationSample.javaファイルおよびMain.javaファイルでは@autherや@version、@param、@returnなどJavadocに関連するアノテーションの記述例も載せています。

まとめ

ここでは、アノテーションについて使い方や独自のアノテーションを作成する方法について説明しました。

アノテーションにはオーバーライド時にメソッドの記述の誤記を防止したり、メソッドの再定義や記述途中の警告非表示など便利な機能も多くあります。

便利な機能も多く、またコードを見やすくすることもできるので、使いこなすことができるようにこの記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次