反射
反射機構は、以下の機能を提供します。
実行時の解析クラスで。
ビューには、実行時にオブジェクト。
一般的な操作コード配列を達成するために。
使用して、
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
パッケージ内のクラスField
、Method
およびConstructor
クラスの説明のためのフィールド、メソッド、およびコンストラクタ。Modifier
クラスは提供しstatic
、メソッドや定数を、クラスやメンバーのアクセス修飾子を復号化することができます。
Class
クラスgetXXX
メソッドとgetDeclaredXXX
は全く異なる方法リターンオブジェクトの配列である:前者戻り公共およびスーパークラス(スーパーもしあれば)を返し、(スーパークラスを除く)すべて。
注:Constructor
とMethod
クラス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
式を。