Javaの基本(b)は、反射

反射

反射機構は、以下の機能を提供します。

  • 実行時の解析クラスで。

  • ビューには、実行時にオブジェクト。

  • 一般的な操作コード配列を達成するために。

  • 使用して、Methodオブジェクト。

そのビューの実行時エラーを使用するだけでなく、ブレークカプセル化手順かどうかに注意を払う反射の高い権威のために、。

クラスクラス

実際には、Class情報の保存クラスではなく、オブジェクトを担当します。仮想マシンの型情報はランタイム実行のための適切な方法を選択します。

ObjectクラスgetClassメソッド戻りClass型のインスタンス。したがって、あなたは、オブジェクトの呼び出しにすることができgetClass所属しているオブジェクトに関する情報を取得する方法を。最も一般的なクラス名の一つができますgetNameバッグは、クラス名に含まれている方法を得ること。

// 假设e是某个类的实例
System.out.println(e.getClass().getName());

逆に、によってforName取得方法は、クラス名に対応するClass例。

// 这里要获取Random的Class实例,注意包名
Class cl = Class.forName("java.util.Random");
// 如果输入的类名不存在,会抛出“已检查异常”ClassNotFoundException。

取得するための非常に単純な方法があるClassクラスのオブジェクトは、Javaで直接またはタイプ、であること、voidキーワードを追加した後.class、クラスのオブジェクトのマッチングを取得し、。

Class cl_1 = java.util.Random.class;
Class cl_2 = int.class;
Class cl_3 = Double[].class;

これは、上記取得することであるClass三つの方法のクラスオブジェクトを。

取得しClassたクラスのオブジェクトを、あなたが呼び出すことができるnewInstanceクラスに呼び出すメソッドをデフォルトコンストラクタ、クラスのインスタンスを作成します。ここでは、このクラスの要件は、必要があり、それ以外の場合は例外がスローされます、デフォルトコンストラクタを持っています。あなたが含むパラメータのコンストラクタを使用したい場合は、我々は呼び出す必要がありConstructor、クラスnewInstanceメソッドを。

クラスの使用を反映する能力の分析

ではjava.lang.reflectパッケージ内のクラスFieldMethodおよびConstructorクラスの説明のためのフィールド、メソッド、およびコンストラクタ。Modifierクラスは提供しstatic、メソッドや定数を、クラスやメンバーのアクセス修飾子を復号化することができます。

ClassクラスgetXXXメソッドとgetDeclaredXXXは全く異なる方法リターンオブジェクトの配列である:前者戻り公共およびスーパークラス(スーパーもしあれば)を返し、(スーパークラスを除く)すべて

注:ConstructorMethodクラスgetParameterTypesメソッドは、型コンストラクタのパラメータやメソッドの返すことができるClassオブジェクトの配列を。MethodクラスgetReturnTypeメソッドは、パラメータのメソッドの戻り値の型を返すClassオブジェクトを。

ではModifierクラスの数が存在するstatic boolean検出方法修飾子のための方法。getModifiersこの方法は、改質戻りintビットパターンメモリを、それぞれが修飾子を表します。Modifierクラスも提供toString方法は、図に対応する文字列修飾ビットパターンを返します。

実行時にリフレクションを使用してオブジェクトの分析

オブジェクトは、ドメイン・オブジェクトを決定するために得られた場合は、呼び出すことができるFieldクラスのget(Object obj)オブジェクト内のフィールドの現在の値を取得する方法、及び対応するクラスに格納されたオブジェクトを返します。

// harry是一个员工对象,有一个域name
Employee harry = new Employee("Harry Hacker");
// 通过getClass获取harry所属的类的Class对象cl
Class cl = harry.getClass();
// 通过getDeclaredField("name")获取cl中存储的name域的Field对象f
Field f = cl.getDeclaredField("name");
// f调用get(harry)获取harry这个对象的name域的当前值,并存储在Object对象v中
Object v = f.get(harry);
// v的输出结果是Harry Hacker

ここではnameプライベートドメインである、get方法がスローされますillegalAccessException呼び出すことができるsetAccessibleでカバーする方法Java、アクセス制御を、反射のデフォルトの動作は、もはや制限はありません。

f.setAccessible(true);
反射アレイのための一般的なコードを書きます

使用java.lang.reflectパッケージは、Array動的に作成された配列クラスを拡張することができます。以来、アレイが作成された配列の要素の型は、あなたがすることができない、記録されているObjectクラスのニーズのオブジェクトの配列にオブジェクトの配列を変換します。このように、使用する必要がArray静的クラスのメソッドをnewInstance(componentType, newLength)拡張処理の後、この配列は、に変換することができるように、オブジェクトの所望のクラスの配列を構築するためにObjectクラスして、元のクラスに変換されます。次のように拡張された操作は次のとおりです。

public static Object CopyOf(Object a, int newLength)
{
    // 首先获取对象a的Class对象cl
    Class cl = a.getClass();
    // 判断a是否是Array类对象
    if (!cl.isArray()) return null;
    // 确定数组对应的类型
    Class componentType = cl.getComponentType();
    // 获取数组a的长度
    int length = Array.getLength(a);
    // 构造一个和a的类型相同的新Array数组,长度为newLength
    Object newArray = Array.newInstance(componentType, newLength);
    // 将a的内容复制到新的Array数组中(有一种realloc的既视感)
    System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));
    return newArray;
}
任意のメソッドを呼び出します

使用Methodクラスのinvokeメソッドは、オブジェクトの任意のメソッドを呼び出すことができます。invoke次のように署名があります。

// 第一个参数obj是隐式参数,对于静态方法,被设置为null,后面的显式参数表示被调用的对象数组。
Object invoke(Object obj, Object... args)

暗黙のパラメータが実際にあるのでMethod、オブジェクト、あなたが呼び出す必要がgetMethod呼び出したいメソッドを取得するためにMethodオブジェクトを。

// 第一个参数是方法名的字符串,后面的显式参数表示方法的参数类型,用来辨别同名不同参数的方法。
Method getMethod(String name, Class... parameterTypes)

推奨:使用した場合にのみ、必要なMethodオブジェクト、それはインターフェースと使用するのが最善であるlambda式を。

おすすめ

転載: www.cnblogs.com/aries99c/p/12388585.html