我正在尝试在由String标识的Java类上调用main方法。在实际程序中,类标识符将是一个变量,但目前我正在尝试:
try {
Class c = Class.forName("Arena");
Class[] aarg = new Class[1];
aarg[0] = String[].class;
Method m = c.getMethod("main", aarg); // Needs parameter class list
m.invoke(newargs);
}
catch (Exception e) {
System.err.println(e);
}
首先,我得到一个编译器警告(Athena是我当前正在使用的类的名称):
Note: Athena.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
然后在测试中出现此异常:
java.lang.IllegalArgumentException: wrong number of arguments
我感觉最主要的是我不知道如何将main()
的参数识别为String类的数组(未能找到其示例),但是也许我想不到的更多。
invoke()
中,您可以忽略第一个参数并传递null
,因为main()
是static
方法。第二个被声明为varargs参数,但是在我的测试中,它不能正常工作。我强制转换为单个Object
而不是Object
s的长度1的数组。这里,Object
用作原始类型,因为invoke()
在编译时不了解其参数,但可以在运行时将其强制转换为所需的类型。invoke()
中使用的可变参数在这种情况下不起作用,因为它期望可以组合为Object[]
的类型Object[]
或逗号分隔的值。问题是String[]
是Object[]
的子类。因此,String[]
方法不是将String[]
解释为单个invoke()
参数,而是认为您正在尝试为其提供一组不同的String
/ Object
输入。
内部逻辑:method.invoke(null, 1, 2, 3)
变为带有Object[]
元素的int
。 3个独立的int
参数method.invoke(null, "hello", "wow", "ok")
变为带有Object[]
元素的String
。 3个独立的String
参数method.invoke(null, String[] { "hello", "wow", "ok" })
变为带有Object[]
元素的String
。 3个独立的String
参数,即使我们只需要一个参数String[]
坦白地说,这不是您的错,API缺乏诊断这些问题的良好文档。随时问我问题,这些东西令人困惑。
try {
Class<?> c = Class.forName("Test");
Method m = c.getMethod("main", String[].class); // Needs parameter class list
String[] input = new String[] { "hello world" };
m.invoke(null, (Object) input);
}
catch (Exception e) {
e.printStackTrace();
}
public static void main(String... args) throws InvocationTargetException, IllegalAccessException {
try {
Class<?> c = Class.forName("Arena");
Method mainMethod = c.getMethod("main", String[].class);
String[] arguments = new String[] { "0", "1", "2" };
mainMethod.invoke(null, (Object) arguments);
} catch (Exception e) {
e.printStackTrace();
}
}
public Object invoke(Object obj, Object... args)
[obj
从args调用底层方法的对象]args
用于方法调用的参数
Class c = Class.forName("Arena"); String[] params = null; Method m = c.getMethod("main", String[].class); // Needs parameter class list m.invoke(null,(Object) params);
注意null
作为主要方法的invoke
不需要实例。