Java の高度な機能 - Junit 単体テスト、リフレクション、アノテーション

**

1. Junit 単体テスト

**

テストカテゴリ:

1.黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值
2.白盒测试:需要写代码,关注程序具体的执行流程。Junit是其中一种

このような問題が発生した場合: クラス内に作成できる main メソッドは 1 つだけなので、一度に 1 つのメソッドしかテストできません。複数のメソッドをテストしたい場合、および各メソッドが互いに独立している場合は、Junit を使用できます。それを解決するために。

Junit の使用手順:

1.定义一个测试类
	编写格式建议:
		测试类名:被测试的类名Test,例如CalTest
		包名:xxx.xxx.test,最终放在test包中
2.定义测试方法:可以独立运行
	编写格式建议:
		方法名:test测试的方法名,例如testAdd()
		返回值:void,因为独立运行,不需要返回给调用处
		参数列表:空参,因为独立运行,不需要返回给调用处
3.给方法加上@Test注解,加上以后,就可以独立运行了
4.导入Junit依赖环境,否则加上@Test之后会报错

判定結果:

1.运行后显示红色:失败
2.运行后显示绿色:成功
一般会使用断言操作来处理结果:
	Assert.assertEquals(期望的结果,程序运行的结果);

注釈:

1.@Before:修饰的方法会在测试方法之前被自动执行
	初始化方法:用于资源申请,所有测试方法在执行之前都会执行该方法。我们可以在一个方法前面加上注解@Before,使其成为一个初始化方法。
2.@After:修饰的方法会在测试方法之后自动被执行
	释放资源的方法:在所有测试方法执行完后,都会自动执行该方法。我们可以在一个方法前面加上注解@After,使其成为一个释放资源的方法

注:
単体テストでは、出力を見てもプログラムが正しいかどうかを判断できないため、通常、出力は書き込まれません。出力の存在は、コード構文が正しいことを示すだけですが、ロジックが間違っている可能性があります。
したがって、コードに問題があるかどうかを判断するために、通常はアサーション操作を使用します。アサーションの結果と真の結果を比較します。アサーションが成功した場合は実行後に緑色で表示され、アサーションが失敗した場合は緑色で表示されます。実行後は赤色で表示されます。

**

2. リフレクション:フレームデザインの魂

**
2.1 フレームワーク

フレームワークは中途半端なソフトウェアです。フレームワークに基づいてソフトウェア開発を行うことができ、コーディングを簡素化できます。
フレームワークを書くにはリフレクションが必要ですが、フレームワークの外側の部分にはリフレクション技術は必要ありません。したがって、リフレクションはフレームワークの内部実装原則です。

2.2 反射

クラスのさまざまなコンポーネントを他のオブジェクトにカプセル化するのがリフレクション メカニズムです。

たとえば、Class オブジェクトは次のようになります。

成员变量封装成了Field[] fileds对象
构造方法封装成了Constructor[] constructors对象
成员方法封装成了Method[] methods对象

リフレクションの利点:

1.可以在程序运行过程中,操作这些对象。
	例如String str = "abc";
	str.写完(.)之后,会将字符串对象str所具有的的方法都提示出来,因为将所有的方法都封装到了Method[]数组中,这就是用到了反射技术,IDEA打开期间都可以提示,这就是程序运行时
2.可以解耦,即降低程序的耦合性,提高程序的可扩展性

2.3 Java コードの 3 つの段階に対応して、Class オブジェクトを取得するには 3 つの方法があります。

1.Source源代码阶段:Class.forName("全类名")
	将字节码文件加载进内存,返回Class对象
	全类名即包名+类名
	因为传递的是字符串,所以多用于配置文件,将类名定义在配置文件中,读取文件,加载类
2.Class对象阶段:类名.Class
	通过类名的属性class获取
	多用于参数的传递
3.Runtime运行时阶段:对象.getClass()
	getClass方法是封装在Object类中的方法,所以所有对象都可以调用该方法
	多用于对象的获取字节码的方式
4.结论(重要!!!)
	同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不论通过哪种方式获取的Class对象都是同一个

2.4 Class オブジェクトの関数 - 取得関数:

1.获取成员变量们
    Field[] getFields():获取所有public修饰的成员变量
    Field[] getField(String name):获取指定名称的public修饰的成员变量

    Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
    Field[] getDeclaredField(String name):获取指定名称的成员变量,需忽略访问权限修饰符的安全检查
2.获取构造方法们
    Constructor[] getConstructors()
    Constructor[] getConstructor(类<?>... parameterTypes)

    Constructor[] getDeclaredConstructors()
    Constructor[] getDeclaredConstructor(类<?>... parameterTypes)
3.获取成员方法们
    Method[] getMethods()
    Method[] getMethod(String name, 类<?>... parameterTypes)

    Method[] getDeclaredMethods()
    Method[] getDeclaredMethod(String name, 类<?>... parameterTypes)
4.获取类名
    String getName()

注意:带Declared的方法都需要忽略访问权限修饰符的安全检查
    setAccessible(true)

ファイル (メンバー変数):

操作:
    1.设置值
        void set(Object obj, Object value)
    2.获取值
        Object get(Object obj)
    3.忽略访问权限修饰符的安全检查
        setAccessible(true):暴力反射

コンストラクタ:

创建对象:
    T newInstance(Object... initargs)
如果使用空参数构造方法创建对象,可以简化操作:使用Class对象的newInstance方法

メソッド (メンバーメソッド):

执行方法:
    Object invoke(Object obj, Object... args)
获取方法名称:
    String getName:获取方法名称

2.5 Java コードがコンピュータ内で通過する 3 つの段階

1) ソースソースコード段階 (.java --> .class)

.java ファイルが javac によってコンパイルされると、.class バイトコード ファイルが生成されます。.class ファイルに含まれる主な内容は、メンバー変数、構築メソッド、およびメンバー メソッドです。

2) クラスオブジェクト段階

Xxx.class (バイトコード ファイル) は、クラス ローダー (ClassLoader) を通じてメモリにロードできます。
メモリ内には、バイトコードを記述するオブジェクトがあります。Java には、Class クラスと呼ばれるクラスがあります。このオブジェクトは、Class クラス オブジェクトです。Class クラスは、バイトコード ファイルのいくつかの一般的な動作と属性を記述するために使用されます。

Class オブジェクトの主要部分は次のとおりです。

成员变量:封装为了Field[] fields对象
构造方法:封装为了Constructor[] constructors对象
成员方法:封装为了Method[] methods对象

3) ランタイムステージ

Class オブジェクトのいくつかの動作を通じて実際のオブジェクトを作成できます。

2.6 「フレームワーク」を書く

必要:

不能改变该类的任何代码,可以创建任意类的对象,可以执行任意方法

テクノロジー:

配置文件、反射

成し遂げる:

1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2.在程序中加载读取配置文件
3.使用反射技术来加载类文件到内存中
4.创建对象
5.执行方法

コード:

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //可以创建任意类的对象,可以执行任意方法

        /*
            前提:不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法
         */

        //下述方法,在创建不同对象,执行其方法的时候,需要修改代码
//        Person p = new Person();
//        p.eat();

//        Student stu = new Student();
//        stu.sleep();

        //1.加载配置文件
        //1.1 创建Properties对象
        Properties prop = new Properties();
        //1.2 加载配置文件,转换为一个集合
        //1.2.1 获取文件的路径,即获取class目录下的配置文件:使用【类加载器】,后续可以将字节码文件加载进内存
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        prop.load(is);

        //2.获取配置文件中定义的数据
        String className = prop.getProperty("className");
        String methodName = prop.getProperty("methodName");

        //3.加载该类进内存
        Class cls = Class.forName(className);

        //4.创建对象
        Object obj = cls.newInstance();
        //5.获取方法对象
        Method method = cls.getMethod(methodName);
        //6.执行方法
        method.invoke(obj);
    }
}

**

3. 注意事項

**

3.1 コンセプト

アノテーションはアノテーションでもあり、JDK5 以降、Java ではアノテーションであるメタデータのサポートが追加されています。
アノテーションとアノテーションには一定の違いがあります。アノテーションは、コード内の特別なマークとして理解できます。これらのマークは、コンパイル、クラスのロード、および実行時に読み取られ、対応する処理を実行できます。コメントはプログラムを言葉で説明するもので、プログラマーが見ることができます。
注釈を使用すると、開発者は元のコードやロジックを変更することなく、ソース コードに補足情報を埋め込むことができます。

3.2 機能分類

1) ドキュメントの作成: コード内で特定されたメタデータ (注釈) を通じてドキュメントを生成します [ドキュメント ドキュメントの生成]

2) コード分析: コード内で特定されたメタデータ (注釈) を通じてコードを分析します [リフレクションを使用]

3) コンパイル チェック: コンパイラは、コード内で識別されるメタデータ (アノテーション) を介して基本的なコンパイル チェック [オーバーライド] を実装でき、正しく書き換えられればコンパイルに合格します。

3.3 アノテーションの使用方法

@アノテーション名

3.4 Java は 5 つの基本的なアノテーションを提供します。

1.@Override: このアノテーションでマークされたメソッドが親クラス (インターフェイス) から継承されているかどうかを確認します。

2.@非推奨: この注釈でマークされたコンテンツは、古いことを示します。

3.@SuppressWarnings: 警告を抑制します。通常、すべての警告を抑制するにはパラメータ all が渡されます: @SuppressWarnings("all")

4.@SafeVarargs: ヒープ汚染警告

5.@FunctionalInterface: 機能インターフェイス

3.5 カスタム注釈

1) フォーマット

元注解
public @interface 注解名称{
    属性列表;
}

2) エッセンス

Annotation は本質的にはインターフェイスであり、デフォルトで Annotation インターフェイスを継承します。

3) 特性

属性: インターフェイスで定義できるメンバー メソッド。つまり、抽象メソッドはアノテーションの属性です。

属性には次の要件があります。

1.属性的返回值类型有如下选择:

    基本数据类型
    String(字符串)
    枚举
    注解
    以上类型的数组

2.定义了属性,在使用时,需要给属性赋值

    1.如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值

    2.如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。

    3.数组赋值时,值使用{}包裹:
        大括号中有多个值:例如@MyAnno(strs = {"abc", "def"})
        大括号中只有一个值,则大括号{}可以省略,例如@MyAnno(strs =  "abc")

3.6 メタアノテーション

メタアノテーションは、アノテーションを説明するために使用されるアノテーションです。

1) @Target: アノテーションが機能できる場所 (クラスまたはメソッド上) を記述します。

ElementType取值:

     TYPE:可以作用于类上,@Target(value = ElementType.TYPE)
     METHOD:可以作用于方法上,@Target(value = ElementType.METHOD)
     FIELD:可以作用于成员变量上,@Target(value = ElementType.FIELD)

     若想同时作用于多个位置,可以用大括号{}:@Target(value = {ElementType.TYPE, ElementType.METHOD})
     因为只有一个属性需要赋值,且属性名为value,则可以省略:
         @Target(ElementType.TYPE, ElementType.METHOD)

2) @Target: アノテーションが機能できる場所 (クラスまたはメソッド上) を記述します。

保持ポリシーの値:

SOURCE:当前被描述的注解,【不会】保留到class字节码文件中,【不会】被JVM读取到

CLASS:当前被描述的注解,【会】保留到class字节码文件中,【不会】被JVM读取到

RUNTIME:当前被描述的注解,【会】保留到class字节码文件中,【并被】JVM读取到

注: 通常、カスタム アノテーションは RUNTIME に設定されます。

3) @Documented: アノテーションが API ドキュメントに抽出されるかどうかを記述します。

@Documented //表示MyAnno3这个注解会被抽取到javadoc文档中
public @interface MyAnno3 {
}

4) @Inherited: アノテーションがサブクラスに継承されるかどうかを記述します。

@Inherited  //表示子类自动继承该注解
public @interface MyAnno3 {
}

3.7 アノテーションの使用法の概要

1. 将来的には、ほとんどの場合、カスタム アノテーションの代わりにアノテーションが使用されることになります

1. コンパイラによって使用されます
。 2. TestCheck.java などの解析プログラムによって使用されます
。 3. 注釈はプログラムの一部ではなく、注釈はラベルであると理解できます。

おすすめ

転載: blog.csdn.net/weixin_42214237/article/details/126294276