多くの主流フレームワークはリフレクション テクノロジを使用します。たとえば、ssh フレームワークは、構成ファイルとしての XML とリフレクション テクノロジの 2 つのテクノロジを使用します。
リフレクションに関連するクラスパッケージ。
java.lang.reflect.* および java.lang.Class;
Java のすべての型 (基本型を含む) は Class オブジェクトに対応し、この Class は java.lang.Class です。つまり、各型にはそれに対応する Class オブジェクトがあり、Class にはパブリック コンストラクターがありません。一般公開がないわけではないので注意してください。
クラスオブジェクトの取得方法
次のようにコードをコピーします。
各 object.getCalss() に対して、対応するクラスを取得できます。
.Class.forName(String)、String の書き込みメソッド: パッケージ名.クラス名。パッケージ名.クラス名に対応するオブジェクトが作成されます。 注: 1.2 は参照型にのみ適用されます。
基本型の場合: カプセル化クラス。 TYPE は、対応する基本型の Class オブジェクトを表します。 注: 3 は、基本型にのみ適用されます。
.タイプ、クラス。 <タイプ 4 は汎用です。>
上記の 4 つの方法のうち、動的なのはメソッド 2 だけです。したがって、動的プログラミングを本格的に実現したい場合は、方法 2 のみを使用できます。
各タイプの Class オブジェクトは 1 つだけあります。つまり、アドレスは 1 つだけありますが、タイプが異なれば異なります。
したがって、次の出力結果はすべて true です。
次のようにコードをコピーします。
//ペア型と参照型
クラス c1 = "".getClass();
クラス c2 = Class.forName("java.lang.String");
クラス c3 = String.class;
System.out.println(c1 ==c2);//true
//基本型の場合
クラス番号 1 = 整数.TYPE;
クラス番号2 = int.class;
System.out.println(num1 == num2);//true
クラス内のメンバーの関連メソッドを取得するためのリフレクション
[構造を取得 <パラメータの型に従って>] (通常は宣言なしで使用されます)
次のようにコードをコピーします。
Constructor<T> getConstructor(Class<?>...parameterTypes)
この Class オブジェクトによって表されるクラスの指定されたパブリック コンストラクターを反映する Constructor オブジェクトを返します。
コンストラクター<?>[] getConstructors()
この Class オブジェクトによって表されるクラスのすべてのパブリック コンストラクターを反映する Constructor オブジェクトを含む配列を返します。
Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes)
この Class オブジェクトによって表されるクラスまたはインターフェイスの指定されたコンストラクター メソッドを反映する Constructor オブジェクトを返します。
コンストラクター<?>[] getDeclaredConstructors()
この Class オブジェクトによって表されるクラスによって宣言されたすべてのコンストラクター メソッドを反映する Constructor オブジェクトの配列を返します。
[属性を取得 <属性名に従って>] (属性は一般にプライベートであるため、通常は宣言された状態で使用されます)
次のようにコードをコピーします。
フィールド getField(文字列名)
この Class オブジェクトによって表されるクラスまたはインターフェイスの指定されたパブリック メンバー フィールドを反映する Field オブジェクトを返します。
フィールド[] getFields()
この Class オブジェクトによって表されるクラスまたはインターフェイスのアクセス可能なすべてのパブリック フィールドを反映する Field オブジェクトを含む配列を返します。
フィールド getDeclaredField(文字列名)
この Class オブジェクトによって表されるクラスまたはインターフェイスの指定された宣言されたフィールドを反映する Field オブジェクトを返します。
フィールド[] getDeclaredFields()
この Class オブジェクトで表されるクラスまたはインターフェイスによって宣言されたすべてのフィールドを反映する Field オブジェクトの配列を返します。
[取得メソッド <メソッド名とパラメータの型>] (通常は宣言なしで使用されます)
次のようにコードをコピーします。
メソッド getMethod(文字列名, Class<?>...parameterTypes)
この Class オブジェクトによって表されるクラスまたはインターフェイスの指定されたパブリック メンバー メソッドを反映する Method オブジェクトを返します。
メソッド[] getMethods()
この Class オブジェクトによって表されるクラスまたはインターフェイスのパブリック メンバー (そのクラスまたはインターフェイスによって宣言されたもの、およびスーパークラスおよびスーパーインターフェイスから継承されたものを含む) メソッドを反映する Method オブジェクトを含む配列を返します。
メソッド getDeclaredMethod(文字列名, Class<?>...parameterTypes)
この Class オブジェクトによって表されるクラスまたはインターフェイスの指定された宣言されたメソッドを反映する Method オブジェクトを返します。
メソッド[] getDeclaredMethods()
この Class オブジェクトで表されるクラスまたはインターフェイスによって宣言されたすべてのメソッドを反映する Method オブジェクトの配列を返します。これには、パブリック メソッド、プロテクト メソッド、デフォルト (パッケージ) アクセス、プライベート メソッドが含まれますが、継承されたメソッドは含まれません。
T newInstance()
この Class オブジェクトによって表されるクラスの新しいインスタンスを作成します。 <new Instance() はオブジェクトを動的に作成できます>
文字列 toString()
オブジェクトを文字列に変換します。
知らせ: newInstance() はパラメーターなしのコンストラクターを呼び出します。クラスにパラメーターなしのコンストラクターがない場合、newInstance() は例外を生成します。
宣言されたメソッドはプライベート性をサポートしますが、継承はサポートしません。宣言されていないメソッドは継承をサポートしますが、プライベート性をサポートせず、パブリックなもののみを取り出すことができます。
したがって、プロパティは通常、プライベートであり、メソッドは通常、宣言なしで取得され、コンストラクターは通常、宣言なしで取得されるため、プロパティは通常、宣言を使用して宣言されます。
インスタンス シミュレーションのリフレクションは、クラス内の関連するプロパティとメソッドを取得します。
リフレクションを使用してプロパティに値を割り当てる
フィールドのメソッド
オブジェクトget(オブジェクトobj)
指定されたオブジェクトのこのフィールドによって表されるフィールドの値を返します。
フィールド f = c.getXXField(プロパティ名);
値 = f.get(オブジェクト);
void set(オブジェクトobj, オブジェクト値)
指定されたオブジェクト変数のこの Field オブジェクトによって表されるフィールドを、指定された新しい値に設定します。
f.set(オブジェクト, 値);
クラス<?> getType()
この Field オブジェクトによって表されるフィールドの宣言された型を識別する Class オブジェクトを返します。
属性のタイプを取得するために使用されます (Class オブジェクトを返します)。
次のようにコードをコピーします。
クラス c = Student.class;
Object obj = c.newInstance() //Studentクラスのオブジェクトを作成
Field f = c.getDeclaredField("name"); //名前属性を取得します。
f.setAccessible(true); //プライベートアクセスを設定します。
f.set(obj, "張三");
System.out.println(f.get(obj)); //obj の name 属性の値を取得します。
リフレクションを使用してコンストラクトを呼び出すコンストラクターへの実際の呼び出しは、 newInstance() メソッドが呼び出されるときです。
次のようにコードをコピーします。
クラス c = Class.forName("com.clazz.reflect.Student");
Constructor con = c.getConstructor(); //構築は実行されません。
Object cObj = c.getConstructor().newInstance();//パラメータなしのコンストラクタを呼び出します
コンストラクター conAll = c.getConstructor(int.class,String.class,int.class);
Object caobj = conAll.newInstance(1001,"zjamgs",234235);//パラメーターを指定してコンストラクターを呼び出します。
System.out.println(caobj); //出力を印刷します。
リフレクションを使用したメソッドの呼び出しオブジェクト.メソッド名(値 1,2,3);
Method m = c.getMethoed(メソッド名, パラメータの型...);
m.invoke (オブジェクト、メソッド呼び出しパラメータ) 基になるメソッドに必要な仮パラメータが 0 の場合、指定された args 配列の長さは 0 または null にすることができます。
次のようにコードをコピーします。
クラス c = Class.forName("com.clazz.reflect.Student");
Object obj = c.newInstance(); // Sutdent オブジェクトを作成します。
Method msetName = c.getMethod("setName", String.class);//obj は型を変換する必要はありません
msetName.invoke(obj, "zhangsan");// setName メソッドを呼び出し、パラメータを渡します。
メソッド msetId = c.getMethod("setId", int.class);
msetId.invoke(obj, 409090202);
System.out.println(obj);
リフレクション応用例エンティティクラス
次のようにコードをコピーします。
パッケージ org.dennisit.reflect.entity;
java.io.Serializableをインポートします。
/**
*
*ユーザー.java
*
* @バージョン: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">メールを送信</a>
*
* @since: 1.0 作成時間: 2013-2-26 01:43:56 pm
*
* TODO: User.java クラスは...に使用されます。
*
*/
public class ユーザーは Serializable{ を実装します
プライベート文字列テスト。
public voidexecute(String name,int age){
System.out.println("name=" + 名前 + ",age=" + 年齢);
}
}
リフレクションテストクラス
次のようにコードをコピーします。
パッケージ org.dennisit.reflect.main;
java.lang.reflect.Fieldをインポートします。
/**
*
* ReflectEx.java
*
* @バージョン: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">メールを送信</a>
*
* @since: 1.0 作成時間: 2013-2-26 01:46:00 pm
*
* TODO: クラス ReflectEx.java は次の目的で使用されます...
*
*/
パブリック クラス ReflectEx {
public static void main(String[] args)throws 例外 {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
Object obj = cls.newInstance(); // ユーザーオブジェクトを作成します
Field f = cls.getDeclaredField("test"); //テスト属性を取得します。
f.setAccessible(true); //プライベート属性テストのアクセス許可を開く
f.set(obj, "zhangsan"); // テストのために再度コピーします
System.out.println(f.get(obj)); //obj のテスト属性値を取得します。
//メソッド名に基づいてメソッドを取得します。
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.invoke(obj, "dennisit",23); //実行メソッドを呼び出す
}
}
運用効果
次のようにコードをコピーします。
張三
名前=デニシット、年齢=23
リフレクティブ動的インスタンス化クラスの作成例
次のようにコードをコピーします。
パッケージ org.dennisit.reflect.main;
java.lang.reflect.Fieldをインポートします。
java.lang.reflect.Methodをインポートします。
java.util.Mapをインポートします。
java.util.Setをインポートします。
/**
*
* DynamicReflect.java
*
* @バージョン: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">メールを送信</a>
*
* @since: 1.0 作成時間: 2013-2-26 01:58:12 pm
*
* TODO: リフレクションを使用した動的インスタンス化の例
*
*/
パブリック クラス DynamicReflect {
public static Object getInstance(String className,Map<String,Object> マップ)throws Exception{
クラス c = Class.forName(className);
オブジェクト obj = c.newInstance(); //オブジェクト オブジェクト
Set<String> Keys = map.keySet(); // 対応する属性をすべて取得します。
Field[] fAll = c.getDeclaredFields() //クラス内のすべてのプロパティを取得します。
for(int i=0;i<fAll.length;i++){
for(String key:keys){ //ループマッチング
if(fAll[i].getName().equals(key)){ //ユーザーが渡した属性が取得したクラスの属性名と一致する場合
Field f = c.getDeclaredField(key);//この属性を取得します
// setXxx() メソッド名を構築します
文字列メソッド名 = "セット" + key.substring(0,1).toUpperCase()+key.substring(1);
Method method = c.getMethod(methodName, f.getType());//構築されたユーザー名に基づいて、対応するメソッドを取得します
Method.invoke(obj, map.get(key));//メソッド呼び出し
}それ以外{
続く;
}
}
}
オブジェクトを返します。
}
}
次に、作成した動的リフレクションのインスタンス化の例をテストします。
エンティティクラス
次のようにコードをコピーします。
パッケージ org.dennisit.reflect.entity;
java.io.Serializableをインポートします。
/**
*
*ユーザー.java
*
* @バージョン: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">メールを送信</a>
*
* @since: 1.0 作成時間: 2013-2-26 01:43:56 pm
*
* TODO: エンティティクラス
*
*/
public class ユーザーは Serializable{ を実装します
プライベート文字列名。
プライベートの年齢。
プライベート文字列電子メール。
public User() { //パラメータコンストラクタは必須ではありません
}
//getter() と setter()
}
メインテストクラス
次のようにコードをコピーします。
パッケージ org.dennisit.reflect.main;
java.util.HashMapをインポートします。
java.util.Mapをインポートします。
org.dennisit.reflect.entity.User をインポートします。
/**
*
* ReflectEx.java
*
* @バージョン: 1.1
*
* @author: Su Ruonian<a href="mailto:
[email protected]">メールを送信</a>
*
* @since: 1.0 作成時間: 2013-2-26 01:46:00 pm
*
* TODO: クラス ReflectEx.java は次の目的で使用されます...
*
*/
パブリック クラス ReflectEx {
public static void main(String[] args)throws 例外 {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
文字列クラス名 = "org.dennisit.reflect.entity.User";
Map<String,Object> マップ = new HashMap<String, Object>();
map.put("名前", "デニスット");
map.put("年齢", 22);
map.put("電子メール", "[email protected]");
ユーザー user = (ユーザー)DynamicReflect.getInstance(クラス名, マップ);
System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
}
}
プログラム実行結果
次のようにコードをコピーします。