Java Annotation(二)


まずjdkが持参したjava.lang.annotationパッケージのソースファイルを分析します.
 
      1、Target.java
 
@Documented  
@Retention(RetentionPolicy.RUNTIME)   
@Target(ElementType.ANNOTATION_TYPE)   
public @interface  Target {   
      ElementType[] value();   
}  

 
 
       @interfaceはキーワードで、annotationsを設計するときにclassまたはinterfaceキーワードではなく@interfaceとして定義する必要があります.
説明:すべてのAnnotationはjava.lang.annotationというインタフェースを自動的に継承するので、他のクラスやインタフェースを継承することはできません.
 
       2、Retention.java
 
@Documented  
@Retention(RetentionPolicy.RUNTIME)   
@Target(ElementType.ANNOTATION_TYPE)   
public @interface Retention {   
      RetentionPolicy value();   
}  

 
       3、RetentionPolicy.java
 
public enum RetentionPolicy {   
      OURCE,   
      CLASS,   
      RUNTIME   
}  

 
      これはenumタイプで、SOURCE、CLASS、RUNTIMEの3つの値があります.      SOURCEはこのAnnotationタイプの情報がプログラムのソースコードにしか残らないことを表しており、ソースコードがコンパイルされた後、Annotationのデータは消え、コンパイルされた.classファイルには残らない.      ClassSは、このAnnotationタイプの情報をプログラムのソースコードに保存するとともに、コンパイルされた.classファイルにも保存します.実行時には、これらの情報を仮想マシン(JVM)にロードすることはありません.AnnotationタイプのRetention値を設定していない場合、システムのデフォルト値はCLASSです.       3つ目は、RUNTIMEで、ソースコード、コンパイルされた.classファイルに情報を保持し、実行時にこれらの情報をJVMにロードすることを示しています.例を挙げると、@OverrideのRetentionをSOURCEに設定し、コンパイルに成功したらこれらのチェックの情報は不要です.逆に,@Deprecatedの中のRetentionをRUNTIMEとすると,コンパイル時にどのDeprecatedされたメソッドを使用するかを警告する以外は,実行時にそのメソッドがDeprecatedされたかどうかを調べることができる.
       4、ElementType.java
 
public enum ElementType {   
     TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR,   
     LOCAL_VARIABLE, ANNOTATION_TYPE,PACKAGE   
}

 
   @Targetの中のElementTypeはAnnotationタイプがどの要素で使えるかを指定するために使われています.説明します:TYPE(タイプ)、FIELD(属性)、METHOD(方法)、PARAMETER(パラメータ)、CONTRUCTOR(構造関数)、LOCAL_VARIABLE(ローカル変数)、ANNOTATION_TYPE、PACKAGE(パッケージ)のうちのTYPE(タイプ)とは、Class、Interface、Enum、Annotationタイプで用いることができる.   また,1のソースコードから分かるように,@Target自身も自己宣言を用いており,ANNOTATION_TYPEの上   Annotationタイプが@Targetがどの要素に使用するかを指定していない場合は、任意の要素の上に使用することができ、ここでの要素は上記の8種類を指す.   いくつかの正しい例を挙げます.   @Target(ElementType.METHOD)    @Target(value=ElementType.METHOD)    @Target(ElementType.METHOD,ElementType.CONSTRUCTOR)      具体的にはjavadocドキュメントを参照してください
 
Annotationの例を挙げる
  次のクラスファイルを作成します.
   1、 Description.java
 
   
 
package com.annotation.demo;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Description {

	String value();
}

 
    説明:すべてのAnnotationはjava.lang.annotationというインタフェースを自動的に継承するので、他のクラスやインタフェースを継承することはできません.   最も重要な点は、Annotationタイプのパラメータをどのように設定するかです.   第一に、publicまたはデフォルト(default)の2つのアクセス権でのみ修飾できます.たとえば、String value()です.ここではメソッドをdefaulデフォルトタイプに設定する.   第二に、パラメータメンバーは、基本タイプbyte、short、char、int、long、float、double、booleanの8種類の基本データ型とString、Enum、Class、annotationsなどのデータ型、およびこれらのタイプの配列しか使用できません.例えば、String value()ここのパラメータメンバーはStringです.   第三に、パラメータメンバーが1つしかない場合は、パラメータ名を「value」に設定し、カッコを付けることが望ましい.例:上記の例ではパラメータメンバーが1つしかない.
 
 
    2、Name.java
 
   
package com.annotation.demo;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {

	String originate();
	String community();
	public enum CommunityNumber{LITTle,ORDINARY,WELL}
	CommunityNumber number() default CommunityNumber.WELL;
}

 
 
  3、JavaEyer.java
  
  
package com.annotation.demo;

@Description("javaeye, is good!")
public class JavaEyer {
	@Name(originate="   :robbin",community="javaeye")
	public String getName(){
		return null;
	}
}

 
 
  4、JavaEyer情報を抽出できるクラスAnnotationTest.javaを書く
 
  
package com.annotation.demo;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

public class AnnotationTest {

	public static void main(String[] args) throws Exception{
		String CLASS_NAME = "com.annotation.demo.JavaEyer";
		Class test = Class.forName(CLASS_NAME);
		Method[] method =test.getMethods();
		boolean flag = test.isAnnotationPresent(Description.class);
		if(flag){
			Description des = (Description)test.getAnnotation(Description.class);
			System.out.println("  : "+des.value());
		}
		
		Set<Method> set = new HashSet<Method>();
		for(int i=0;i<method.length;i++){
			boolean otherFlag = method[i].isAnnotationPresent(Name.class);
			if(otherFlag)
				set.add(method[i]);
		}
		
		for(Method m : set){
			Name name = m.getAnnotation(Name.class);
			System.out.println(name.originate());
			System.out.println("     : "+name.community());
		}
			
	}
}

 
 
テスト結果:
 
説明:javaeye,is good!創始者:robbinが作成したコミュニティ:javaeye
 
転載先:http://lighter.iteye.com