リスト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
-------------------------------------------------------------------------------