詳細なJavaのメタアノテーションと使用カスタム注釈

1元のメモ

1.1メタ注釈は何ですか

実際には、いわゆるメタアノテーションは、他のノートにコメントして注釈を付けることができ、その春の注釈の注釈機能と組み合わせる組み合わせノートと呼ばれる注釈付きノート。

1.2元のノート4種類の

注釈型に注釈をもとにJDK標準的な4つの注釈で提供、我々はメタアノテーション(メタアノテーション)を呼び出し、彼らは以下のとおりです。

  • @ターゲット
  • @保持
  • @Documented
  • @継承されました

私たちは、カスタム注釈型に注釈を付けるためにこれらの4元のノートを使用することができます。

1.3 @Targetコメント

注釈役割がするターゲット:注釈の使用を記載している(つまり、修正注釈が任意の場所で使用することができる)の範囲。

それが注釈されていることをベース注釈を説明するための注釈をターゲットが目標範囲を変更することができる:注釈がパッケージ、型(クラス、インタフェース、列挙、注釈カテゴリ)、クラスのメンバ(メソッド、コンストラクタ、メンバ変数を変更するために使用することができ、使用@Targetアノテーションクラスがより明確に定義することができる列挙値)、メソッドの引数と、このようなループ変数とローカル変数(キャッチ・パラメータ)は、範囲のElementTypeで定義されたオブジェクトを修正するために使用することができるかを知ります列挙。
ソース

@Documented  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.ANNOTATION_TYPE)  
public @interface Target {  
    ElementType[] value();  
}  
复制代码

ElementType

public enum ElementType {
 
    TYPE, // 类、接口、枚举类
 
    FIELD, // 成员变量(包括:枚举常量)
 
    METHOD, // 成员方法
 
    PARAMETER, // 方法参数
 
    CONSTRUCTOR, // 构造方法
 
    LOCAL_VARIABLE, // 局部变量
 
    ANNOTATION_TYPE, // 注解类
 
    PACKAGE, // 可用于修饰:包
 
    TYPE_PARAMETER, // 类型参数,JDK 1.8 新增
 
    TYPE_USE // 使用类型的任何地方,JDK 1.8 新增
 
}
复制代码

1.4 @Retention

Reteniton注釈機能がある:注釈は(すなわち:注釈を保持するそのクラスの変更に記載されている)保持時間を記載しました。

Retenitonアノテーションをクラスに注釈を付けるために使用される他のクラスの後にそれらの注釈付きノートに限定さRetentionPolicy列挙で定義されるように、場合に、3つの戦略の合計まで保持することができる。
RetentionPolicy

public enum RetentionPolicy {
 
    SOURCE,    // 源文件保留
    CLASS,       // 编译期保留,默认值
    RUNTIME   // 运行期保留,可通过反射去获取注解信息
}
复制代码

後者は前者缶効果も達成することができなければならないライフサイクル長SOURCE <CLASS <RUNTIME、。実行時の注釈情報に動的に取得するために必要であれば、それだけでRUNTIME注釈を使用することになり、あなたはコンパイル時にいくつかの前処理操作をしたい場合は、そのような補助的なコード(例えばButterKnife)の数を生成し、CLASSアノテーションを使用するために、唯一のいくつかのチェックを行う場合このよう@Overrideおよび@SuppressWarningsなどの操作は、あなたがSOURCEのコメントを選択することができます。

1.5 @Documented

注釈の役割を文書化:あなたはその注釈情報を保持したい場合はjavadocツールを使用してヘルプファイルを生成するために、クラスで説明したように。
ここ@Documented役割を確認し、我々は、カスタムアノテーションを作成します。

@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyDocumentedt {

    public String value() default "这是@Documented注解为文档添加的注释";

}
复制代码

その後方法でテストクラスを作成し、クラスはカスタムコメントを追加しています

@MyDocumentedt
public class MyDocumentedTest {
    /**
     * 测试 document
     * @return String the response
     */
    @MyDocumentedt
    public String test(){
        return "sdfadsf";
    }
}
复制代码

、javaファイルディレクトリを開き、コマンドラインを開き、次のように入力します

javac .\MyDocumentedt.java .\MyDocumentedTest.java
复制代码
javadoc -d doc .\MyDocumentedTest.java .\MyDocumentedt.java
复制代码

オープン、生成されたドキュメントフォルダを開き index.html 、クラスやメソッドの上に見つけることができますがMyDocumentedt注釈情報を保持しています。

1.6 @Inherited

継承された注釈の役割がある:(クラスは注釈が変更された@Inherited使用している場合、それは自動的にノートのサブクラスを持つことになります)のノートが継承される変更することができるようにすること。
コードを確認するには、カスタムアノテーションを作成します

@Target({ElementType.TYPE})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInherited {
}
复制代码

検証

@MyInherited
public class A {
    public static void main(String[] args) {
        System.out.println(A.class.getAnnotation(MyInherited.class));
        System.out.println(B.class.getAnnotation(MyInherited.class));
        System.out.println(C.class.getAnnotation(MyInherited.class));
    }
}

class B extends A{
}

class C extends B{
}
复制代码

mainメソッドを実行するには、コンソールからの印刷に関する情報を見ることができます

1.7繰り返し注釈@Repeatable

繰り返し注釈は:すなわち、同じ注釈型宣言型(クラス、プロパティまたはメソッド)の前に複数回の使用を可能にします。

java8前に、旧プログラム要素とコメントだけの同じタイプの最大を持つことができ、同じ要素の前のノートの同じタイプの複数の場合は、注釈を使用しなければならない「コンテナを。」java8の練習の前に

public @interface Roles {
    Role[] roles();
}
复制代码
public @interface Roles {
    Role[] value();
}
复制代码
public class RoleAnnoTest {
    @Roles(roles = {@Role(roleName = "role1"), @Role(roleName = "role2")})
    public String doString(){
        return "";
    }
}
复制代码

java8は、次のように使用され、繰り返しのノートの後に増加しました。

public @interface Roles {
    Role[] value();
}
复制代码
@Repeatable(Roles.class)
public @interface Role {
    String roleName();
}
复制代码
public class RoleAnnoTest {
    @Role(roleName = "role1")
    @Role(roleName = "role2")
    public String doString(){
        return "";
    }
}
复制代码

あなたが使用して、直接役割のコメントを再利用することができ、ストレージノートの役割を、指して、重複したノートの役割に加え、@Repeatableを作成するときの違いは、あります。上記の例から見て、Javaの8は従来の考え方、それが読めるの練習に適しています。しかし、それはまだコンテナノートを定義する必要があります。

同じ効果は、2つの方法により得られます。実際には、より多くの重複したノートは配列要素「コンテナ」の注釈値のメンバーとして扱われます:リピート注釈は、書き込みが幻想である簡素化するだけの単純化表現、です。

1.8型注釈

Java8のElementType列挙には、注釈はどこタイプに使用することができ、注釈このタイプの注釈と呼ばれる修飾@Target(ElementType_TYPE_USE)を使用して定義することができ、2列挙値TYPE_PARAMETER、TYPE_USEを増加させます。

java8前に、ノートはプログラム要素の様々なだけを使用することができる(インタフェースを定義する定義されたクラス、メソッドを定義し、メンバ変数の定義...)。java8開始から、型注釈を入力するようにどこでも使用することができます。

TYPE_PARAMETERは:ノートは、宣言の型パラメータに書き込むことができることを示しています。

TYPE_USE:注釈のタイプは、以下の位置の使用を可能にするように、任意のさらなる使用の代わりに使用することができ表します。

  • (新しいキーワードで作成された)オブジェクトを作成します。
  • 型変換
  • 道具を使用して、インターフェイスを実装
  • 使用すると、文の例外がスローされるスロー
public class TypeUserTest {

    public static void main(String[] args) {
        String str = "str";
        Object obj = (@isNotNull Object) str;
    }

}

@Target(ElementType.TYPE_USE)
@interface isNotNull{
}
复制代码

このパーベイシブ・アノテーションは、それによってプログラムの堅牢性を向上させる、コンパイラは厳しいコード検査を行うことができます。

2カスタム注釈

以上の検討を経てどのように一つのこと、次の行とコンテキストでカスタム注釈メタ注釈があることを理解し始めている。カスタムアノテーションを

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

    public String value() default "";
}
复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Sex {

    public enum GenderType {
        Male("男"),
        Female("女");
        private String genderStr;
        private GenderType(String arg0) {
            this.genderStr = arg0;
        }
        @Override
        public String toString() {
            return genderStr;
        }
    }
    GenderType gender() default GenderType.Male;
}
复制代码

エンティティクラスのカスタム注釈

@Data
public class User {

    @Name(value = "wtj")
    public String name;
    public String age;
    @Sex(gender = Sex.GenderType.Male)
    public String sex;

}
复制代码

テスト

public class AnnotionUtils {

    public static String getInfo(Class<?> cs){
        String result = "";
        //通过反射获取所有声明的字段
        Field[] declaredFields = cs.getDeclaredFields();
        //获取所有字段
        for (Field field : declaredFields){
            if(field.isAnnotationPresent(Name.class)){
                //获取程序元素上的注解
                Name annotation = field.getAnnotation(Name.class);
                String value = annotation.value();
                result += (field.getName() + ":" + value + "\n");
            }
            if(field.isAnnotationPresent(Sex.class)){
                Sex annotation = field.getAnnotation(Sex.class);
                String value = annotation.gender().name();
                result += (field.getName() + ":" + value + "\n");
            }
        }
        return result;
    }

    public static void main(String[] args){
        String info = getInfo(User.class);
        System.out.println(info);
    }

}
复制代码

着信データは、アノテーションを使用する場合は、コンソールで見ることができた後に実行する主な方法。
上記のデモを使用した簡単な注釈で、当然のことながら、実際の作業で使用することは比較的複雑になり、私たちは、ビジネス要件に基づいて必要とパッケージをコードし、使用するカスタム注釈を必要とします。

おすすめ

転載: juejin.im/post/5d7f34b3f265da03ee6a894c