English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
概要
Javaでは1.5バージョン引注注釈Annotation、いわゆるJavaアノテーションは、ソースコードに直接使用できる语法元データです。/メソッド/変数/引数/パッケージ名なども注釈で使用できます。Javadocタグとは異なり、コンパイラはclassファイルの生成時に注釈コードを保持し、また、プログラムの実行中(run)-time)注釈を使用することができます。Java仮想機は注釈を保持し、そのため、反射を通じて注釈Annotationの関連情報を取得することができます。
内蔵注釈
実際には、私たちがよく遭遇するアノテーション、例えば@Override、@Deprecatedなどがあります。これらはJDKに内蔵されたアノテーションであり、まずJava内蔵のアノテーションの主な種類を見てみましょう。
•Javaコードに適用されるアノテーション
◦@Override は、特定のメソッドがオーバーライドメソッドであるかどうかを確認し、そのメソッドが親クラスまたは実装したインターフェースに見つからない場合、コンパイルエラーが発生します。
◦@Deprecated は、特定のメソッドやクラスが廃止されたことを示し、そのクラスやメソッドを使用するとコンパイルプロセスで警告が表示されます。
◦@SuppressWarnings は、コンパイラに標注されたパラメータに関する警告を無視するように通知します。
◦@SafeVarargs は、泛型パラメータを持つメソッドまたはコンストラクタの呼び出しに関する警告を無視します。1.7注釈の追加
◦@FunctionalInterface は、宣言されたインターフェースが機能性インターフェースとして使用されることを示しています。1.8注釈の追加
•他のアノテーションに使用されるアノテーションは、メタアノテーション(Meta Annotation)と呼ばれます。
◦@Retention は、標注されたアノテーションがいつ使用されるか(つまり、アノテーションがいつ保存されるか)を示しています。
■ソースコード中のみ保持され、コンパイルプロセス中に削除されます(RetentionPolicy.RUNTIME)。
■アノテーションはコンパイルプロセス中にclassファイルに保存され、classファイルが読み込まれた際に無視されます(RetentionPolicy.CLASS)。
■アノテーションはclassファイルの読み込み時に読み取られます、つまり、実行中にアノテーションが使用可能であり、反射を通じてアノテーションの情報を取得できます(RetentionPolicy.RUNTIME)。
◦@Documented は、Javadocの生成時に標注されたアノテーションがJavadocドキュメントに書き込まれることを示しています。
◦@Target は、標注されたアノテーションの作用範囲を示しています。
■ElementType.TYPE: クラス、インターフェース(アノテーションタイプを含む)またはenumの宣言を説明するために使用されます。
■ElementType.FIELD: 域の説明に使用されます。
■ElementType.METHOD: メソッドの説明に使用されます。
■ElementType.PARAMETER: パラメータの説明に使用されます。
■ElementType.CONSTRUCTOR: 构造関数の説明に使用されます。
■ElementType.LOCAL_VARIABLE: 局部変数の説明に使用されます。
■ElementType.ANNOTATION_TYPE: アノテーションの説明に使用されます。
■ElementType.PACKAGE: パッケージを説明するために使用されます。
◦@Inherited は、標注されたアノテーションが継承されることを示しています。つまり、@Inherited で修飾されたアノテーションがクラスに使用された場合、そのアノテーションもそのクラスのサブクラスに適用されます。
◦@Repeatable は、同一オブジェクトに複数回注釈を適用できることを示します。1.9注釈の追加
カスタム注釈
注釈について多くのことを説明しましたが、特にメタ注釈に注目してください。カスタム注釈を定義する際には、通常メタ注釈を使用してサポートを受けます。カスタム注釈の形式はpublic @interface 注釈名 {定義体}で、@interfaceでカスタム注釈を定義すると、自動的にjava.lang.annotation.Annotationインターフェースを継承します。カスタム注釈を定義する際には、他の注釈やインターフェースを継承することはできません。注釈内で宣言されたメソッドは実際には注釈パラメータを宣言しています。メソッドの名前がパラメータの名前であり、リターン値のタイプがパラメータのタイプです。デフォルト値を指定するためにdefaultを使用できます。
カスタム注釈はとても簡単で、@interfaceを使って定義します。以下の通りです。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface ClassInfo { String author() default "Wang"; String date(); String comments(); }
カスタム注釈ClassInfoを定義しました。@Retentionにより、この注釈はプログラムの実行中にも有効です;@Target(ElementType.TYPE)により、ClassInfo注釈はクラス、インターフェース、enumの宣言に作用します;@Documented
ClassInfo情報はJavadocドキュメントに書き込めることが説明されています。
カスタム注釈の中の注釈パラメータを見てみましょう。中には三つの注釈パラメータがあり、注釈パラメータにはデフォルト値を設定できます。例えば、author注釈パラメータはデフォルト値がWangで、他の二つのパラメータにはデフォルト値はありません。
もう一つのカスタム注釈を見てみましょう。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MethodInfo { String description() default "No Description"; String date(); }
このカスタム注釈MethodInfoはメソッドに作用し、プログラムの実行中にもこの注釈は存在します;中には二つの注釈パラメータがあります。
注釈パラメータの定義(メソッドの定義)は、publicまたはdefaultの二つのアクセス権限修飾子で指定できます。パラメータのタイプは以下の通りをサポートしています。
•八種基本データ型(byte、int、short、long、float、double、char、boolean)
•Stringタイプ
•Classタイプ
•enumタイプ
•Annotationタイプ
•以上のすべての型の配列
注解の使用
上記の2つの注解に加えて、Field範囲の注解を追加しました。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface FieldInfo { String type(); String name(); }
カスタムの注解内の注解パラメータにデフォルト値が指定されていない場合、カスタム注解を使用する際にこれらのパラメータに値を設定する必要があります。そうしないとコンパイラがエラーを報告します。
注解の使用方法を見てみましょう:
@ClassInfo(author = "wang", date = "2016/9/13, comments = "annotation demo") public class AnnotationDemo { @FieldInfo(type = "public", name = "firstField") public int firstField; @FieldInfo(type = "private", name = "secondField") private String secondField; @MethodInfo(description = "AnnotationDemo内のメソッド", name = "firstMethod") public void firstMethod(String value) { System.out.printf("first method involved"); } @MethodInfo(description = "AnnotationDemo内のメソッド", name="secondMethod") private void secondMethod() { System.out.printf("first method involved"); } }
注解情報の取得
注解情報を取得するには、まず注解がプログラムの実行中に存在することを保証する必要があります。したがって、一般的にはカスタムの注解に@Retention(RetentionPolicy.RUNTIME)メタ注解を追加します。そのため、プログラムの実行中に反射を使用して注解情報を取得することができます。反射の説明については、この記事を参照してください。
public class AnnotationTest {}} public static void main(String[] args) { resolveClassAnnotationInfo(AnnotationDemo.class); resolveFieldAnnotationInfo(AnnotationDemo.class); resolveMethodAnnotationInfo(AnnotationDemo.class); } private static void resolveClassAnnotationInfo(Class<?> clz) { // このクラスにClassInfoアノテーションがあるかどうかを判断します if(clz.isAnnotationPresent(ClassInfo.class)) { ClassInfo classInfo = (ClassInfo) clz.getAnnotation(ClassInfo.class); System.out.println(classInfo.author()) + " " + classInfo.comments()) + " " + classInfo.date()); } } private static void resolveFieldAnnotationInfo(Class<?> clz) { Field[] fields = clz.getDeclaredFields(); for (Field field : fields) { if(field.isAnnotationPresent(FieldInfo.class)) { FieldInfo fieldInfo = (FieldInfo) field.getAnnotation(FieldInfo.class); System.out.println(fieldInfo.type()) + " " + fieldInfo.name()); } } } private static void resolveMethodAnnotationInfo(Class<?> clz) { Method[] methods = clz.getDeclaredMethods(); for (Method method : methods) {}} if(method.isAnnotationPresent(MethodInfo.class)) { MethodInfo methodInfo = (MethodInfo) method.getAnnotation(MethodInfo.class); System.out.println(methodInfo.name() + " " + methodInfo.description()); } } } }
クラス内のFieldを反射で取得/Methodなど、getAnnotation()またはgetAnnotations()を使用して関連するアノテーションを取得し、特定のアノテーションを取得すると、特定の情報を取得できます。
以下の実行結果を出力します:
図-1 実行結果図
まとめ
Javaの初心者やある程度の経験があるJava開発者にとって、Javaアノテーションに触れる機会は少なく、実際にはアノテーションを使用することも少なく、コードではよく見かけますが、この記事はアノテーションの簡単な紹介であり、コードレベルでは読みやすいです。
これで本文のすべてが終わり、皆さんの学習に役立つことを願っています。また、呐喊教程を多くのサポートをお願いします。
声明:本文の内容はインターネットから収集され、著作権者に帰属します。インターネットユーザーにより自発的に貢献し、自己でアップロードされた内容であり、本サイトは所有権を有しておらず、編集もされていません。著作権侵害を疑う内容があれば、メールで:notice#wまでお知らせください。3codebox.com(メールを送信する際、#を@に変更してください)で通報し、関連する証拠を提供してください。一旦確認が取れましたら、本サイトは即座に侵害を疑われるコンテンツを削除します。