如何在java中动态实例化具有不同数量参数的java类?

时间:2018-02-14 16:55:02

标签: java reflection

我有许多类,其中包含不同类型的参数的构造函数。 我得到了我需要使用的类,以及它的文本构造函数:

"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

2 个答案:

答案 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;在你的代码中,因为你不知道它在运行时是什么,所以你必须使用反射来处理它。