JAvaカスタム注釈および注釈パラメータの取得

5110 ワード

以前は注釈が何の役に立つか分からなかったが、今はフレームワークを学び、あちこちに注釈があることに気づいた.注釈の原理を理解する必要があります
注釈を深く学ぶには、自分の注釈を定義し、注釈を使用する必要があります.自分の注釈を定義する前に、Javaが提供してくれたメタ注釈と関連定義注釈の文法を理解する必要があります.
メタ注記:
メタ注釈の役割は、他の注釈を注釈することです.Java5.0は、他のannotationタイプについて説明するために使用される4つの標準的なmeta-annotationタイプを定義する.Java5.0定義のメタ注記:
1.@Target,
2.@Retention,
3.@Documented,
4.@Inherited

これらのタイプとサポートされているクラスはjavaです.lang.annotationパッケージから見つかります.各メタ注釈の役割と対応するサブパラメータの使用説明を見てみましょう.
@Target:
@Targetは、Annotationによって修飾されたオブジェクト範囲を示します.Annotationはpackages、types(クラス、インタフェース、列挙、Annotationタイプ)、タイプメンバー(メソッド、構築メソッド、メンバー変数、列挙値)、メソッドパラメータおよびローカル変数(ループ変数、catchパラメータなど).Annotationタイプの宣言でtargetを使用すると、その修飾のターゲットがより明確になります.
≪アクション|Actions|emdw≫:注釈を記述するための使用範囲(すなわち、説明された注釈がどこで使用できるか)
値(ElementType)は次のとおりです.
1.CONSTRUCTOR:       
2.FIELD:     
3.LOCAL_VARIABLE:        
4.METHOD:      
5.PACKAGE:     
6.PARAMETER:      
7.TYPE:     、  (      )  enum  

使用例:
@Target(ElementType.TYPE)
public @interface Table {
    /**
     *        ,       
     * @return
     */
    public String tableName() default "className";
}

@Target(ElementType.FIELD)
public @interface NoDBColumn {

}

注記Tableは、注釈クラス、インタフェース(注釈タイプを含む)またはenum宣言に使用できますが、注記NoDBColumnは、注釈クラスのメンバー変数にのみ使用できます.
@Retention:
@Retentionは、このAnnotationが保持される時間の長さを定義します.一部のAnnotationはソースコードにのみ表示され、コンパイラによって破棄されます.他のいくつかはclassファイルにコンパイルされています.classファイルにコンパイルされたAnnotationは、仮想マシンによって無視される可能性がありますが、classがマウントされたときに読み込まれるものもあります(Annotationとclassは使用上分離されているため、classの実行には影響しません.このmeta-Annotationを使用すると、Annotationの「ライフサイクル」を制限できます.
≪アクション|Actions|emdw≫:注釈情報を保存するには、注釈のライフサイクルを記述するためにどのレベルが必要かを示します(すなわち、説明された注釈がどの範囲で有効かを示します).
値(RetentionPoicy)は次のとおりです.
    1.SOURCE:ソースファイルで有効(すなわちソースファイル予約)2.CLASS:classファイルで有効(すなわちclass予約)3.RUNTIME:実行時に有効(すなわち実行時予約)
Retention meta-annotationタイプにはjavaからの値をとる唯一のvalueがメンバーとして存在する.lang.annotation.RetentionPolicyの列挙タイプ値.具体的な例は次のとおりです.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}

 
Column注釈のRetentionPolicyの属性値はRUTIMEであり、このように注釈プロセッサは反射することによってその注釈の属性値を取得することができ、それによっていくつかの実行時の論理処理を行うことができる.
@Documented:
@Documentedは、他のタイプのannotationを記述するために、注釈されたプログラムメンバーの共通APIとして使用されるべきであり、javadocのようなツールでドキュメント化することができる.Documentedはタグ注記で、メンバーはいません.
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}

@Inherited:
@Inheritedメタ注釈はタグ注釈であり、@Inheritedはある注釈のタイプが継承されていることを述べている.@Inherited修飾を使用したannotationタイプがclassに使用される場合、このannotationはclassのサブクラスに使用されます.
注意:@Inherited annotationタイプは、マークアップされたclassのサブクラスに継承されます.クラスは、実装されたインタフェースからannotationを継承しません.メソッドは、再ロードされたメソッドからannotationを継承しません.
@Inherited annotationタイプ表記のannotationのRetentionがRetentionPolicyである場合RUNTIMEでは、反射APIがこの継承性を強化する.Javaを使用するとlang.reflect@Inherited annotationタイプのannotationをクエリーすると、反射コードチェックが展開されます.classとその親クラスが、指定したannotationタイプが発見されるまで、またはクラス継承構造の最上位に到達するまでチェックします.
インスタンスコード:
/**
 * 
 * @author peida
 *
 */
@Inherited
public @interface Greeting {
    public enum FontColor{ BULE,RED,GREEN};
    String name();
    FontColor fontColor() default FontColor.GREEN;
}

カスタム注記インスタンス
注釈をカスタマイズ:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target(ElementType.METHOD)//       
public @interface MyAnnotation {
	String name()default "   ";
	int abilityNum()default 1;
	String[] abilityNames()default {"   "};
}

テストコード:注釈のパラメータを取得できるかどうかをテストします.
public class TestAnnotation {

	@MyAnnotation(name="   ",abilityNum=2,abilityNames= {"    ","    "})
	public void people1(String name,int age) {
	}

	@MyAnnotation(name="  ",abilityNum=2,abilityNames= {"    ","    "})
	public void people2(String name,int age) {
	}

	@MyAnnotation     //    ,      
	public void people3(String name,int age) {
	}

	public static void main(String[] args){

		Method[] methods=TestAnnotation.class.getMethods();//        

		for(Method m:methods) { //      
			if(m.isAnnotationPresent(MyAnnotation.class)) {//       MyAnnotation  

				MyAnnotation myAnno=m.getAnnotation(MyAnnotation.class);

				System.out.print(myAnno.name()+" " +myAnno.abilityNum()+"   : ");

				for(String abilityName:myAnno.abilityNames()) {
					System.out.print(abilityName+" ");
				}
				System.out.println();
			}
			
		}
	}
}

出力結果:
   2   :           

    2   :           

    1   :