新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。気づけば社会人3年目に突入。

学習記録:Java魂 9章 実用的なリフレクション

[Java] Javaの学習

内容:9章 実用的なリフレクション

リフレクション
  • Javaの中で最も理解されていない特性だが、最も強力な特性でもある
  • リフレクションにより、作成したツールがどのオブジェクトに大しても動作するようになる
  • コードはより複雑になるが、システム構築が早く保守も楽
リフレクションの基本
public static void printMethodInfo(final Object obj) {
	Class type = obj.getClass();
	// java.lang.refrectパッケージのMethodオブジェクトの配列を返す	
	final Method[] methods = type.getMethods();
	for (int i = 0; i < methods.length; ++i) {
		// メソッド情報の表示
		System.out.println(methods[i]);
	}
}

/*
 * 出力例:
 * Personクラスに定義されているメソッドを表示
 * public void Person.setFirsName(java.lang.String)
 * 継承されたメソッドも表示される
 * public final native void java.lang.Object.notify()
 *
 */
    • Classクラスに定義されたgetDeclaredMethods()との違い
public class MethodInfoDemo {
	// "set"で始まり引数にString型を1つ持つメソッドを使用し、パラメータにhogeを設定
	public static void hogeStrings(final Object obj)
			throws IllegalAccessException, IllegalArgumentException,
			InvocationTargetException {
		final String PREFIX = "set";
		// Method型の配列を取得
		Method[] methods = obj.getClass().getMethods();
		for (int i = 0; i < methods.length; ++i) {
			// メソッド名がsetから始まり、
			if (methods[i].getName().startsWith(PREFIX)) {
				// Stringをパラメータとするメソッドを、
				if (methods[i].getParameterTypes()[0] == String.class) {
					// 引数に"hoge"を入れて実行する
					methods[i].invoke(obj, new Object[] { new String("hoge") });
				}
			}
		}
	}
リフレクションとグレートリフレクション
  • リフレクションのプログラマツールは、java.lang.reflectパッケージだけでなくJDKの中核の各所に存在
  • このツールはよくグレートリフレクションと呼ばれる
  • java.langパッケージ
    • Classクラス
      • オブジェクトのクラスについて、どのようなフィールド・メソッドがあるのか
      • どのパッケージに入っているのか
    • Objectクラス
      • オブジェクトのClassインスタンスを取得できる
      • リフレクションを使ったメソッドなどでも、パラメータとして使用
    • Packageクラス(※余り使わない)
  • java.lang.reflectパッケージ
    • メソッドの動的呼び出しとフィールドの動的割当て・取り出しを行うユーティリティ
    • Classでフィールド・メソッド一覧を呼び出すと、それらがreflectパッケージのクラスのインスタンスとして返ってくる
    • fieldクラス
      • フィールドの説明とアクセスする手段が含まれる
      • フィールドの値を設定したり取り出したりできる
    • Methodクラス
    • Modifierクラス
      • クラス・フィールド・メソッドのビットフィールド修飾子をデコードするのに使用
      • private/public/static/transientのどれかを判別できる
    • Proxyクラス
      • 動的プロキシクラスを作成
      • 特定のインタフェースを実装するオブジェクトを作成するのに使う
      • ex) データオブジェクトに対し、そのオブジェクトへの変更可能なインタフェースを提供するProxyを作成
    • AccessibleObjectクラス
      • 基本となるクラス、MethodやFieldなどはこのクラスを継承
      • privateなどのアクセス性を無視できる、他に方法がないときしか使わないのを推奨
      • (直列化のときに使われる、privateフィールドにもアクセスする必要があるので)