Java注釈の概要

5446 ワード

注釈とは
注釈は注釈と異なり、注釈はクラスファイルに書き込まれず、注釈はクラスファイルに書き込まれ、コードの解析支援メカニズムである.特定のコードに注釈を付けることで、実行時にこのコードを「特殊処理」することができます.一般的なJavaの標準注記を例にとると、Javaの内蔵注記は@Override:親メソッドを上書きする必要があるメソッドを修飾し、その注釈を修飾するメソッドは子クラスで親を上書きしなければならない3つあります.@SuppressWarnnings:Javaコンパイルにクラス、メソッドなどのメンバーへの警告を通知します.@Deprecate:タグが古い方法で、後続のバージョンではこの方法が推奨されていないことを示します.このメソッドはクラスに残って「継続性」のみを表します.標準的な注釈を使用する方法は非常に簡単です.次のようになります.
@Override
public void info(){
 ......
}

標準的な注釈に加えて、ユーザーは自分の注釈を定義することができます.簡単な例を挙げます.
public @interface MyTag {
    String name() default "";
    int age() default -1;
}

ここではMyTagという名前の注記を作成しました.@interfaceがあるのは、java.lang.Annotationのインタフェースを実現したことを示しています.注記は本質的にクラスでもあり、名前とageの2つのメンバーが定義されています.注記では、メンバーを同様の方法で表します.defaultは、メンバーが定義されていない場合のデフォルト値を表します.Javaでは4つの標準的なmeta-annotation(メタ注釈)が定義されており、メタ注釈の役割は他の注釈を注釈することである.1.@Target:注釈の使用範囲を説明し、java.lang.annotation.ElementTypeの列挙値から取り、ElementTypeの値はCONTRUCTOR(コンストラクタ)、FIELD(ドメイン)、LOCAL_VARIABLE(ローカル変数)、METHOD(メソッド)、PACKAGE(パッケージ)、TYPE(クラス、インタフェース)、ANNOTATION_TYPE(注記タイプ)、PARAMETER(パラメータ).2.@Retention:java.lang.annotation.RetentionPolicy,CLASS(デフォルト、class有効)、SOURCE(ソースファイル有効)、RUNTIME(最も一般的で、実行時有効)からの注釈の保持時間.3.@Documented:注釈はjavadocに記録され、注釈情報もjavadocが生成したドキュメントに表示されることを示します.4.@Inherited:注釈が同類を継承していることを示します.子クラスが親クラスを継承する場合、親クラスがその注釈を持つ注釈子クラスも継承されます.メタ注釈を使用する方法は非常に簡単で、私たちがカスタマイズした注釈に@を加えるだけでいいです.
@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
@Documented
@Inherited
public @interface MyTag {
    String name() default "";
    int age() default -1;
}

注釈の応用と処理
注記を使用する場合は、注記のTargetを考慮し、Target要素に@タグを使用する必要があります.次のようになります.
public class MyTagTest {
    @MyTag(name="Aline" , age=25)
    public void info(String name) {
        System.out.println("info"+name);
    }
    @MyTag(name="Prin" , age=26)
    public void info2() {
        System.out.println("Info2");
    }
}

ここでは、前にカスタマイズした注釈を使用して方法を修飾し、修飾時に(name=value)の方法で値を割り当てます.ここでは、要素に注釈を適用しました.注釈の要素を位置決めして処理するために、注釈プロセッサを定義する必要があります.ここでは、反射によって注釈メソッドを呼び出します.ここでtry...catchはツールを使用して自動的に生成されるため、長いように見えますが、try...catchの部分は無視できます.
    public void processAnno(Object obj) {
        Class<?> cl = obj.getClass();
        for(Method m : cl.getDeclaredMethods()) {
            MyTag tag = m.getAnnotation(MyTag.class);
            if (tag!=null) {
              if(tag.name().equals("Prin")) {
                try {
                    m.invoke(obj);
                } catch (Exception ex) {
                    ex.printStackTrace();
                  } 
               }
              else if(tag.name().equals("Aline")) {
                try {
                    m.invoke(obj, tag.name());
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
          }
        }
    }

ここではまずgetDeclaredMethods()メソッドを用いてすべてのclassファイルのメソッドを取得し,次にメソッド配列を逐一スキャンし,annotationがあれば判断処理を行う.テストクラスは次のように記述されます.
public static void main(String args[]){
        MyTagTest mtt = new MyTagTest();
        mtt.processAnno(mtt);
    }

出力結果:Info 2 infoAline
本文は主に以下のネット記事を参考にします.http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html