リスト3は、レポート機能以外の、Fieldの読み書き、Method, Constructorの呼び出し といった reflectionの機能のサンプルです。このプログラムは、もっぱら先の Rectangleクラスに働きかけます。出力結果をつけておきました。このプログラムと 出力を、是非、解読してください。この基本的なサンプル・プログラムが理解でき たら、もう一度、前章での、ちょっと高度な invokeメソッドの使い方を復習して ください。
---< リスト 3 >---------------------------------------------------------------- import java.lang.reflect.*; public class setRect { public static void main(String argv[]) { Class Rectangle; Object RectObj; try { Rectangle = Class.forName("Rectangle"); RectObj = Rectangle.newInstance(); } catch (Exception ex) { System.out.println("Could not insantiate class Rectangle" ); ex.printStackTrace(); return; } try { // フィールドを、名前(String)で獲得する。 // フィールドは、名前で一意に決まる。 Field widthField = Rectangle.getField("width"); Field heightField = Rectangle.getField("height"); // コンストラクタの引数の型。 // *.TYPEは、primitive type 、通常のクラスは、*.class となる。 Class pTypes1[] ={ Integer.TYPE, Integer.TYPE }; // コンストラクタは、引数の型の配列で一意に決まる。 Constructor Cons = Rectangle.getConstructor(pTypes1); // メソッドの引数の型。 Class pTypes2[] ={ Integer.TYPE } ; // メソッドを指定するには、名前と、引数の型の二つの情報が必要である Method SetWidth = Rectangle.getMethod("setWidth" ,pTypes2); Method SetHeight = Rectangle.getMethod("setHeight",pTypes2); // 引数を持たないメソッドの型は、長さが0の引数の型の配列で指定。 Class pTypes3[] ={} ; Method PrintArea = Rectangle.getMethod("printArea",pTypes3); // 少し苦しいが、mainの引数の型の表現。 Class pTypes4[] = { Array.newInstance(String.class,0).getClass() }; Method Main = Rectangle.getMethod("main", pTypes4 ) ; // 引数なしのメソッドに渡される引数。 Object VOID[] = {}; // 引数無しで、mainを呼ぶときの引数。先のVOIDは、メソッド自体が、 // 引数を持たないという意味なので、String[]という型の引数を一つ持つ // mainに VOIDを渡すと、「引数の型があわない」というエラーになる。 // String nonArg[] = {}; Object NULL[] = { nonArg }; としても良い。 Object NULL[] = { null } ; System.out.println("----------------------------"); // フィールドの値の獲得。 getIntの引数に注意。 System.out.println("Width : " + widthField.getInt(RectObj) ); System.out.println("Height : " + heightField.getInt(RectObj)); System.out.println("----------------------------"); // フィールドの値の設定。 同じく、getIntの引数に注意。 widthField.setInt(RectObj,3); heightField.setInt(RectObj,4); // メソッド printAreaの呼び出し。 PrintArea.invoke(RectObj, VOID ); System.out.println("----------------------------"); // メソッドに渡される引数(Object)の配列。 // primitive typeは、wrapされる。 Object args1[] = { new Integer(10) }; // setter メソッドの呼び出し。 SetWidth.invoke(RectObj, args1 ); Object args2[] = { new Integer(11) }; SetHeight.invoke(RectObj, args2 ); PrintArea.invoke(RectObj, VOID ); System.out.println("----------------------------"); Object args3[] = { new Integer(12), new Integer(13) }; // コンストラクタの呼び出しは、newInstanceを使う。 Object RectObj2 = Cons.newInstance(args3); PrintArea.invoke(RectObj2, VOID ); System.out.println("----------------------------"); // mainを、引数なしで呼び出す。 Main.invoke(RectObj, NULL); } catch (Exception ex) { System.out.println("Caught exception: " + ex); ex.printStackTrace(); } } } <出力> ---------------------------- Width : 1 Height : 1 ---------------------------- Width : 3 Height: 4 Area : 12 ---------------------------- Width : 10 Height: 11 Area : 110 ---------------------------- Width : 12 Height: 13 Area : 156 ---------------------------- Width : 3 Height: 4 Area : 12 --------------- Width : 5 Height: 6 Area : 30 -------------------------------------------------------------------------------