Stackにクラス名とメソッド名やフィールド名を突っ込んでそれを実行するプログラムを作った。メソッドを呼び出す場合は引数、引数の数、メソッド名、クラス名、staticでなければオブジェクト。フィールドの場合はフィールド名、クラス名、staticでなければオブジェクトの順でスタックに積む。コンストラクタは引数、引数の数、クラス名で。で、フィールドや返り値、生成したインスタンスはスタックに積む。これをつかってそのうち何かやる
import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException ; import java.util.Stack; public class Main{ public static void main(String[] args) throws Exception{ Stack<Object> stack = new Stack<Object>(); stack.push("Hello World"); stack.push(1); stack.push("println"); stack.push("java.io.PrintStream"); stack.push("out"); stack.push("java.lang.System"); stack.push(Main.getField(stack, true)); stack.push(Main.invokeMethod(stack, false)); stack.pop(); stack.push(0); stack.push("getHost"); stack.push("java.net.URL"); stack.push("http://google.com"); stack.push(1); stack.push("java.net.URL"); stack.push(Main.callConstructor(stack)); stack.push(Main.invokeMethod(stack, false)); System.out.println(stack.pop()); } private static Object callConstructor(Stack<Object> stack) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { String className = stack.pop().toString(); int parameterCount = Integer.parseInt(stack.pop().toString()); Class<?>[] types = new Class<?>[parameterCount]; Object[] args = new Object[parameterCount]; for(int i = 0; i < parameterCount; i++){ Object arg = stack.pop(); types[i] = arg.getClass(); args[i] = arg; } return Main.callConstructor(className, types, args); } private static Object callConstructor(String className, Class<?>[] types, Object[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<?> clazz = Class.forName(className); Constructor constructor = clazz.getConstructor(types); return constructor.newInstance(args); } private static Object getField(Stack<Object> stack, boolean isStatic) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException{ Object target = null; if(!isStatic) target = stack.pop(); String className = stack.pop().toString(); String fieldName = stack.pop().toString(); return Main.getField(className, target, fieldName); } private static Object getField(String className, Object target, String fieldName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException{ Class<?> clazz = Class.forName(className); Field field = clazz.getField(fieldName); return field.get(target); } private static Object invokeMethod(Stack<Object> stack, boolean isStatic) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { Object target = null; if(!isStatic) target = stack.pop(); String className = stack.pop().toString(); String methodName = stack.pop().toString(); int parameterCount = Integer.parseInt(stack.pop().toString()); Class<?>[] types = new Class<?>[parameterCount]; Object[] args = new Object[parameterCount]; for(int i = 0; i < parameterCount; i++){ Object arg = stack.pop(); types[i] = arg.getClass(); args[i] = arg; } return Main.invokeMethod(className, target, methodName, types, args); } private static Object invokeMethod(String className, Object target, String methodName, Class<?>[] types, Object[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { Class<?> clazz = Class.forName(className); Method method = clazz.getMethod(methodName, types); return method.invoke(target, args); } }