我有许多类,其中包含不同类型的参数的构造函数。 我得到了我需要使用的类,以及它的文本构造函数:
"TheClassIWant parameter1 1234 parameter2 5678"
或:
"AnotherClass parameter1 3456"
我将上面的字符串分成一个类名为("TheClassIWant")
的字符串和一个参数数组(p[])
。现在我使用:
Class<?> cl = Class.forName("TheClassIWant")
和构造函数使用:
Constructor<?>[] cons = cl.getDeclaredConstructors();
我可以使用以下命令查看构造函数的参数:
Class<?>[] types = cons[1].getParameterTypes();
当我有许多构造函数参数可能每次都变化时,如何创建类的newInstance? 例如,我可以这样做:
TheClassIWant cl = cons[1].newInstance(p[1],p[2],p[3],p[4]);
但字符串“AnotherClass parameter1 3456”会导致Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
答案 0 :(得分:0)
传递给newInstance
的参数必须符合构造函数的类型,因此如果有构造函数
public TheClassIWant(String param1, int param2, String param3, int param4);
你需要称之为
cons[1].invoke(p[1], Integer.valueOf(p[2]), p[3], Integer.valueOf(p[4]));
你得到的例外是因为你传递了四个字符串。
我不确定是否有一个通用的解决方案,因为可能有一个包含两个构造函数的类:
public TheClassIWant(String param1, int param2, String param3, int param4);
和
public TheClassIWant(String param1, String param2, String param3, String param4);
两者都“适合”,你只能猜测哪一个是特定实例化的正确。
顺便说一句:getDeclaredConstructors
没有特定的顺序返回构造函数,所以有一天可能会返回第一个构造函数,之后的第二个构造函数会返回。我怀疑你在这里有一个工作概念的另一个原因。
答案 1 :(得分:0)
这是因为newInstance方法接受了不同数量的参数,但它们必须完全符合getParameterTypes()的类型。
在你的情况下,你将String对象传递给构造函数,因此IllegalArgumentException。
您需要做的是将String参数解析为正确的类,然后将它们传递给构造函数。
使用您的示例:
String[] tokens = "AnotherClass parameter1 3456".split(" ");
Object[] params = new Object[tokens.length-1];
Constructor c = Class.forName(tokens[0]).getDeclaredConstructors()[0];
Class<?>[] types = c.getParameterTypes();
for (int i=0;i<params.length;i++) {
params[0] = parse(tokens[i+1], types[i]);
}
Object obj = c.newInstance(params);
所以困难的部分是编写方法
private Object parse(String str, Class t);
为每个参数的课程。
此外,您无法声明类的变量&#34; AnotherClass&#34;在你的代码中,因为你不知道它在运行时是什么,所以你必须使用反射来处理它。