Javaの学習ログ(26):注釈、メモシミュレーション@Test

継続的に更新JavaEEの学習ログ---->必見!JavaEEの学習ルート(記事要約)

コメント

ノート概要

定義:注釈(アノテーション)、また、メタデータとして知られています。コードレベルを説明してください。これは、JDK1.5の特徴であり、後のクラス、インタフェース、列挙が同じレベルにある導入します。これは、パッケージ、クラス、フィールド、メソッド、ローカル変数、パラメータの前に宣言することができ、これらの要素のための方法のように、コメントを説明します。

役割カテゴリ

  • ドキュメント執筆:識別された文書によって生成された注釈付きコードを[例えば、文書ドキュメントのドキュメントを生成]
  • コード分​​析:コード識別コードに注釈を付けることによって分析[例えば、注釈は反射】
  • コンパイル検査:そのように同定された注釈コードによって、コンパイラは、基本的なチェックをコンパイルすることができる[例えば、オーバーライド]

共通の注意事項

  1. @author:著者の名前を識別するために使用されます
  2. @version:ファイル、クラス、メソッド:物体、スコープを識別するためのバージョン番号。
  3. @Override:それはメソッドが存在しない場合は、親クラスを親クラスメソッドのオーバーライドでコンパイラに伝えるために、メソッドの宣言を変更するために使用、コンパイルが失敗します。

カスタム注釈

カスタム注:使用キーワード@interface

格式:
    public @interface 注解名{
        属性;
    }
public @interface MyAnnotation01 {
}

カスタム属性で注釈を付けます。属性は、抽象メソッドあって、デフォルトとして見ることができます

格式:
    public @interface 注解名{
        修饰符 数据类型 属性名();
        修饰符 数据类型 属性名() default 默认值;
    }

説明

  • 修飾子:公共抽象的な、デフォルトを使用して固定され、書き込みにはありません。
  • データの種類:
  1. 8つの基本データ型(int型、float型、ブール、バイト、ダブル、文字、ロング、ショート)
  2. String型、クラス型、列挙型、注釈の種類
  3. 一次元アレイの上記タイプの全て

コード例:カスタム属性で注釈付け

public @interface MyAnnotation {
    //定义一个int类型的属性,不包含默认值
    public abstract int a();
    //定义一个double类型的属性,默认值为8.8
    public abstract double d() default 8.8;
    //定义一个String[]类型的属性
    public abstract String[] arr();
    //定义一个Class类型的属性
    public abstract Class clazz();
    //定义一个注解类型的属性
    MyAnnotation01 my01();
    //定义一个枚举类型的属性
    public abstract Color c();
}

注釈を使用します

使用注釈:(オーバーライド@テスト@)と同様のように

範囲
注釈は、パッケージで使用することができ、クラス、メソッド、メンバ変数、工法、ローカル変数...
、同じ名前を持つ注釈同じ場所で一度だけ使用することができます
フォーマット

@注解名(属性名=属性值,属性名=属性值,属性名=属性值...)

用途

  • いいえプロパティは注意:あなたが直接アノテーションを使用することができます@名前は、このアノテーションを使用します
  • ノートの属性があります。
  1. あなたは、プロパティの割り当てのすべてを使用するために、次への道上のキーを使用する必要があります。

  2. プロパティのデフォルト値は、デフォルト値を使用して割り当てることができない持っている、割り当て、新しい値

  3. 注釈限り、およびプロパティ値の名前と呼ばれるようにプロパティが、代入はときに、プロパティ名を省略することができる場合 value=123 或123

  4. 型が配列型のプロパティである場合、割り当てられた時間、{}ラップする必要があり、複数の値;配列長い値であれば、{}を省略してもよいです。 arr={"123","234"} arr="123"

@MyAnnotation01
@MyAnnotation(a = 10,arr = {"篮球","足球"})
public class UseAnnotation {
    private String name;
    @MyAnnotation(a=100,arr = "敲代码")
    private int age;

    public UseAnnotation(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @MyAnnotation02(value = '#')
    public String getName() {
        return name;
    }
    @MyAnnotation02('*')
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

練習
コメントを定義します。ブックを

  • ブックは、プロパティが含まれています:文字列値()
  • タイトルがあって属性:ダブル価格()の価格を、デフォルト値は100元です
  • String []型の作者()複数の著者:それはプロパティが含まれています
public @interface Book {
    //书名
    public abstract String name();
    //价格,默认值100
    public abstract double price() default 100;
    //多为作者
    public abstract String[] authors();
}
//使用Book注解
@Book(name = "Java学习日志",authors="隔夜听风",price = 250)
public class UseBook {
    private String name;
}

元のメモ

元のノート:ノートのJava提供のカスタム注釈を変更するために使用され
@Target:文の注釈位置使用して
プロパティをElementType[] value();
のElementTypeは、列挙型(列挙name属性)であります

ElementType属性值:
   TYPE:用在类,接口上
   FIELD:用在成员变量上
   METHOD:用在方法上
   CONSTRUCTOR:用在构造方法上
   PARAMETER:用在参数上
   LOCAL_VARIABLE:用在局部变量上

II @Retention:カスタム注釈定義ライフサイクル(有効範囲)
の特性をRetentionPolicy value();
RetentionPolicyは、列挙型であります

RetentionPolicy的属性值:
   SOURCE:注解只存在于Java源代码(.java文件中)中,编译生成的字节码文件(.class文件)中就不存在了。
   CLASS:注解存在于Java源代码、编译以后的字节码文件中,运行的时候内存中没有,默认值。
   RUNTIME:注解存在于Java源代码中、编译以后的字节码文件中、运行时内存中,程序可以通过反射获取该注解。

コード例:

@Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Book {
    //书名
    public abstract String name();
    //价格,默认值100
    public abstract double price() default 100;
    //多为作者
    public abstract String[] authors();
}

ノートパース

分析注釈:反射技術、注釈取得
java.lang.reflectの。AnnotatedElement接口
方法:

  • boolean isAnnotationPresent(Class annotationClass);現在のオブジェクトが指定されたノートを持っているかどうかの決定、true、そうでない場合はfalseを返すがあります。

     参数:
         Class annotationClass:判断哪个注解,参数就传递哪个注解的class类型
         如:判断(类 , 构造器 , Executable , 字段 , 方法)是否有Book注解,传递Book.class
    
  • T getAnnotation(Class<T>annotationClass);オブジェクトの現在の注釈オブジェクトに指定された取得。

     参数:
         Class annotationClass:获取哪个注解,参数就传递哪个注解的class类型
         如:获取类 , 构造器 , Executable , 字段 , 方法)的Book注解,传递Book.class
    
  • Annotation[] getAnnotations();現在のオブジェクトを取得し、そのすべての注釈オブジェクトの親から継承されました。

  • Annotation[] getDeclaredAnnotations();親クラスを除く、現在の注釈オブジェクト内のすべてのオブジェクトへのアクセス、。

すべての既知の実装クラス
AccessibleObjectを、クラス、コンストラクタ、実行可能ファイル、フィールド、メソッド、モジュール、パッケージ、パラメータ

コード例:あなたは、次の必要なクラスクラスメソッドの注釈と注釈を

@Book(name = "Java学习日志",authors="隔夜听风",price = 250)
public class Parse {
    @Book(name = "盗墓笔记",authors="南派三叔",price = 111)
    public void getBook(){
        System.out.println(1);
    }
}

ノートや注釈属性クラスを返します

@Test
    public void parseClassAnnotation(){
        //获取类的class文件对象
        Class clazz = Parse.class;
        //使用isAnnotationPresent判断class类上是否有Book注解,必须为RUNTIME生命周期才会true
        boolean b = clazz.isAnnotationPresent(Book.class);
        //System.out.println(b);
        //如果类上存在Book注解,则获取Book注解
        if(b){
            //使用getAnnotation方法获取Class类上的Book注解
            Book book = (Book)clazz.getAnnotation(Book.class);
            System.out.println(book);//@cn.itcast.demo05.annotation.Book(price=250.0, name="Java学习日志", authors={"隔夜听风"})

            //使用注解名.属性名(),通过属性名获取属性值
            System.out.println(book.name());//Java学习日志
            System.out.println(book.price());//250.0
            System.out.println(Arrays.toString(book.authors()));//[隔夜听风]

        }
    }

注釈カテゴリの方法と注釈を獲得

@Test
    public void parseMethodAnnotation(){
        //获取class文件对象
        Class clazz = Parse.class;
        //使用class文件对象中的方法getMethods,获取所有的成员方法
        Method[] methods = clazz.getMethods();
        //遍历数组
        for (Method method : methods) {
            //Method类中有一个方法叫getName,获取方法名称
            //System.out.println(method.getName());
            //使用isAnnotationPresent判断Method方法上是否有Book注解
            boolean b = method.isAnnotationPresent(Book.class);
            //System.out.println(method.getName()+"-->"+b);
            //如果方法上存在Book注解,获取Book注解
            if (b){
                //使用getAnnotation方法获取method上的Book注解
                Book book = method.getAnnotation(Book.class);
                //使用注解名.属性名(),通过属性名获取属性值
                System.out.println(book.name());//Java学习日志
                System.out.println(book.price());//250.0
                System.out.println(Arrays.toString(book.authors()));//[隔夜听风]
            }
        }
    }

アナログ@Testコメント

要件:アナログ@Testノートと呼ばれるカスタム注釈@MyTest

  • この方法を用いる場合@MyTest注釈は実行メソッドを呼び出し(OBJ)可能
  • あなたはこの方法@MyTestコメントではなく、実行メソッドを使用しない場合

実装手順:

  1. テストクラスのクラスファイルオブジェクトを取得UseMyTest
  2. オブジェクトを取得するためにクラスファイルオブジェクトを使用しUseMyTest
  3. 使用するクラスファイルオブジェクトgetMethodsは、クラスメソッドのすべてのメンバーを取得します
  4. ストレージアレイのトラバーサルメンバーメソッド、すべてのメンバメソッドへのアクセス
  5. 判断のMyTestメンバー法上の特定のコメントがあります
  6. メソッドが実行されたinvokeメソッドのメソッドが使用されています

コードの実装:

  1. @MyTestコメント
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)//声明MyTest注解只能在方法上使用
@Retention(RetentionPolicy.RUNTIME)//声明MyTest注解,可以在.java/.class文件/内存中都有效
public @interface MyTest {
}
  1. この方法は、注釈に実行する必要があります
public class UseMyTest {
    @MyTest
    public void test01(){
        System.out.println("test01方法");
    }
    public void test02(){
        System.out.println("test02方法");
    }
    @MyTest
    public void test03(){
        System.out.println("test03方法");
    }
}
  1. @MyTest注釈を達成
public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //1.获取测试类UseMyTest的class文件对象
        Class<?> clazz = Class.forName("cn.itcast.demo07.testall.UseMyTest");
        //2.使用class文件对象获取UseMyTest对象
        Object obj = clazz.newInstance();
        //3.使用class文件对象中的方法getMethods获取类中所有成员方法
        Method[] methods = clazz.getMethods();
        //4.遍历存储成员方法的数组,获取每一个成员方法
        for (Method method : methods) {
            //5.判断成员方法上是否有指定的注解MyTest
            boolean b = method.isAnnotationPresent(MyTest.class);
            if (b){
                //6.有则使用Method中的方法invoke执行该方法
                method.invoke(obj);
            }
        }
    }
}

公開された35元の記事 ウォン称賛43 ビュー6527

おすすめ

転載: blog.csdn.net/Sakuraaaaaaa/article/details/104534414