文字列によるクラス、メソッド、フィールドの操作(forName,getMethod,invoke,getFieldなど)
結論としてrubyみたいなclass_eval->define_methodみたいなデスコンボはできなさそうです。
新しいフィールド、メソッドの生成はJavaでは難しそう。できるかもしれないけど分からなかったです。
既存のクラス、メソッド、フィールドの呼び出しや変更を文字列で操作することは可能そうなのでそこら辺を書いておきます。
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Constructor; public class ReflectTest { public class Inner { String msg; public String getMsg() { return msg; } public void addMsg(String _msg) { msg = _msg + " " + msg; } public Inner(String _msg) { msg = _msg; } } public ReflectTest(String _msg) throws Exception { Class<?> clazz = Class.forName("ReflectTest$Inner"); Constructor[] c = clazz.getConstructors(); ReflectTest.Inner instance = (ReflectTest.Inner) c[0].newInstance(new Object[] {this, "Inner1"}); // 文字列によってのメソッド呼び出し // Class<?>のジェネリクスによって可変長ぽく書けて綺麗 Method addMsg = clazz.getMethod("addMsg", String.class); addMsg.invoke(instance, _msg); Method getMsg = clazz.getMethod("getMsg"); String result = (String)getMsg.invoke(instance); System.out.println(result); } public static void main(String[] args) throws Exception { ReflectTest ob = new ReflectTest("Reflect1"); // 文字列によってクラスをインスタンス化。<?>はジェネリクス // これによって可変長引数のメソッドを呼べるらしい // インナークラスの場合は $ で区切る Class<?> clazz = Class.forName("ReflectTest$Inner"); Constructor[] c = clazz.getConstructors(); // インナークラスの場合コンストラクタの第一引数は // 親クラスのインスタンスを指定する ReflectTest.Inner instance = (ReflectTest.Inner) c[0].newInstance( new Object[] {new ReflectTest("Reflect2"), "Inner2"}); System.out.println(instance.getMsg()); // 文字列によってフィールドにアクセス // private も取れるという。よい子は真似しないように Field msg = clazz.getDeclaredField("msg"); msg.setAccessible(true); msg.set(instance, "Inner3"); System.out.println(instance.getMsg()); }}
http://www.ne.jp/asahi/hishidama/home/tech/java/reflection.html
このサイトがとても詳しくて参考になりました