Javaのアノテーション
Javaアノテーションはコードに関する情報を提供します。Javaアノテーションは、それらが注釈するコードには直接的な影響を与えません。Javaアノテーションのチュートリアルでは、以下の内容を紹介します。
-
- 組み込みのJavaアノテーション
-
- カスタムアノテーションの作成方法
- アノテーションの使用方法とリフレクションAPIを使用してアノテーションを解析する方法.
Javaのアノテーション
Java 1.5では、注釈が導入され、現在ではHibernate、Jersey、SpringなどのJava EEフレームワークで頻繁に使用されています。Javaの注釈は、プログラム自体に埋め込まれたプログラムに関するメタデータです。注釈は、注釈解析ツールやコンパイラによって解析することができます。また、注釈の利用可能性をコンパイル時のみまたはランタイムまで指定することもできます。Javaの注釈がなかった時代は、プログラムのメタデータはJavaコメントまたはJavadocを通じて提供されていましたが、注釈はそれ以上の機能を提供します。注釈のメタデータはランタイム時にも利用可能であり、注釈解析ツールはそれを使用して処理フローを決定することができます。例えば、Jerseyウェブサービスでは、メソッドにURI文字列とともにPATH注釈を追加し、ランタイム時にJerseyがそれを解析して、与えられたURIパターンに対して呼び出すべきメソッドを判断します。
Javaのカスタムアノテーション
カスタムアノテーションの作成は、インターフェースの作成と似ていますが、インターフェースキーワードの前に@シンボルが付けられています。アノテーション内でメソッドを宣言することができます。Javaのカスタムアノテーションの例を見て、その特徴や重要なポイントについて議論しましょう。
package com.scdev.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
String author() default "Pankaj";
String date();
int revision() default 1;
String comments();
}
Javaのアノテーションに関する重要なポイントは以下の通りです:
-
- アノテーションメソッドにはパラメータを持つことはできません。
-
- アノテーションメソッドの戻り値のタイプはプリミティブ、String、Enums、Annotation、またはそれらの配列に制限されています。
-
- Javaのアノテーションメソッドにはデフォルト値を設定することができます。
- アノテーションにはメタアノテーションを付けることができます。メタアノテーションはアノテーションに関する情報を提供するために使用されます。
Javaにおけるメタアノテーション
以下の五つの種類のメタアノテーションが存在します。
-
- @Documented -このアノテーションを使用している要素は、javadocや類似のツールによってドキュメント化されるべきです。このタイプは、そのアノテーションがクライアントによって注釈された要素の使用に影響を与える型の宣言に注釈を付けるために使用されるべきです。型の宣言がDocumentedで注釈されている場合、その注釈は注釈された要素の公開APIの一部となります。
-
- @Target – アノテーションタイプが適用可能なプログラム要素の種類を示します。可能な値には、TYPE、METHOD、CONSTRUCTOR、FIELDなどがあります。Targetメタアノテーションが存在しない場合、アノテーションは任意のプログラム要素に使用できます。
-
- @Inherited – アノテーションタイプが自動的に継承されることを示します。ユーザーがクラス宣言でアノテーションタイプをクエリする場合、そのクラス宣言にこのタイプの注釈がない場合、クラスのスーパークラスが自動的にアノテーションタイプをクエリされます。このプロセスは、このタイプの注釈が見つかるか、またはクラス階層のトップ(Object)に到達するまで繰り返されます。
-
- @Retention – アノテーションされた型の注釈が保持される期間を示します。RetentionPolicy引数を取ります。その可能な値は、SOURCE、CLASS、RUNTIMEです。
- @Repeatable – 注釈の型が繰り返し可能であることを示すために使用されます。
Javaには組み込みの注釈があります。
Javaには、5つの組み込みアノテーションが提供されています。
-
- @Override – スーパークラスのメソッドをオーバーライドしたい場合、このアノテーションを使用してコンパイラにオーバーライドしていることを通知する必要があります。そのため、スーパークラスのメソッドが削除または変更された場合、コンパイラはエラーメッセージを表示します。なぜ常にjavaのオーバーライドアノテーションを使用するべきかを学びましょう。
@Deprecated – メソッドが非推奨であることをコンパイラに知らせるために、このアノテーションを使用する必要があります。Javaでは、javadocでなぜこのメソッドが非推奨であるか、どの代替方法を使用すべきかについての情報を提供するよう推奨しています。
@SuppressWarnings – これは、特定の警告を無視するようコンパイラに指示するためだけのもので、例えばJavaジェネリックスでロータイプを使用する場合です。このアノテーションの保持方針はSOURCEであり、コンパイラによって破棄されます。
@FunctionalInterface – このアノテーションは、インターフェースが関数インターフェースであることを示すためにJava 8で導入されました。
@SafeVarargs – アノテーションされたメソッドやコンストラクタの本体が、その可変長引数パラメータに対して潜在的に安全でない操作を実行しないことをプログラマーが断言しています。
Javaのアノテーションの例
上記の例で、Javaの組み込みアノテーションの使用方法と、私たちが作成したカスタムアノテーションの使用方法を示すJavaの例を見てみましょう。
package com.scdev.annotations;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class AnnotationExample {
public static void main(String[] args) {
}
@Override
@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
public String toString() {
return "Overriden toString method";
}
@Deprecated
@MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
public static void oldMethod() {
System.out.println("old method, don't use it.");
}
@SuppressWarnings({ "unchecked", "deprecation" })
@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
public static void genericsTest() throws FileNotFoundException {
List l = new ArrayList();
l.add("abc");
oldMethod();
}
}
私は上記のJavaアノテーションの例が自己説明的で、異なるケースでのアノテーションの使用方法を示していると信じています。
Javaアノテーションの解析
私たちは、クラスからJavaアノテーションを解析するためにReflectionを使用します。なお、アノテーションの保持方針はRUNTIMEである必要があります。それ以外の場合、その情報は実行時に利用できなくなり、データを取得することができません。
package com.scdev.annotations;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class AnnotationParsing {
public static void main(String[] args) {
try {
for (Method method : AnnotationParsing.class.getClassLoader()
.loadClass(("com.scdev.annotations.AnnotationExample")).getMethods()) {
// checks if MethodInfo annotation is present for the method
if (method.isAnnotationPresent(com.scdev.annotations.MethodInfo.class)) {
try {
// iterates all the annotations available in the method
for (Annotation anno : method.getDeclaredAnnotations()) {
System.out.println("Annotation in Method '" + method + "' : " + anno);
}
MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
if (methodAnno.revision() == 1) {
System.out.println("Method with revision no 1 = " + method);
}
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}
} catch (SecurityException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
上記のプログラムの出力は以下の通りです。
Annotation in Method 'public java.lang.String com.scdev.annotations.AnnotationExample.toString()' : @com.scdev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.scdev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.scdev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.scdev.annotations.AnnotationExample.oldMethod()' : @com.scdev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.scdev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.scdev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.scdev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)
リフレクションAPIは非常に強力であり、JavaやJ2EEのフレームワーク(Spring、Hibernate、JUnitなど)で広く使用されています。Javaのリフレクションを確認してみてください。これでJavaのアノテーションの例のチュートリアルは終わりですが、何か学べたことを願っています。Javaのアノテーションの最新情報:
-
- サーブレットスペック3.0では、サーブレットの設定と初期パラメータの注釈の使用が導入されました。Java Servletチュートリアルで詳細を読むことができます。
- Struts 2では、アクションクラスと結果ページを設定するために注釈を使用することができます。Struts 2 Hello World Annotation Exampleで動作する例を確認してください。
参照:オラクルのウェブサイト