Java Annotation(二)
まずjdkが持参したjava.lang.annotationパッケージのソースファイルを分析します.
1、Target.java
@interfaceはキーワードで、annotationsを設計するときにclassまたはinterfaceキーワードではなく@interfaceとして定義する必要があります.
説明:すべてのAnnotationはjava.lang.annotationというインタフェースを自動的に継承するので、他のクラスやインタフェースを継承することはできません.
2、Retention.java
3、RetentionPolicy.java
これは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
@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
説明:すべての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
3、JavaEyer.java
4、JavaEyer情報を抽出できるクラスAnnotationTest.javaを書く
テスト結果:
説明:javaeye,is good!創始者:robbinが作成したコミュニティ:javaeye
転載先:http://lighter.iteye.com
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