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

Posted

技术标签:

【中文标题】如何在java中动态实例化具有不同数量参数的java类?【英文标题】:How to dynamically instantiate java classes with varying number of arguments in java? 【发布时间】:2018-07-25 08:02:50 【问题描述】:

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

"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

【问题讨论】:

您的代码和this 的组合应该有助于字符串或原始类型的参数。 【参考方案1】:

传递给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 不按特定顺序返回构造函数,所以有一天第一个构造函数可能会被返回,第二个构造函数可能会在之后的第二天返回。我怀疑你在这里有一个可行的概念的另一个原因。

【讨论】:

you can only guess which one is the correct one 这不是真的,你可以getParameterTypes() 来检查构造函数的参数类型。 @isaac 是的。你怎么知道1234 应该是一个数字还是一个恰好是数字的文本来决定你是必须使用纯字符串构造函数还是混合类型的构造函数?【参考方案2】:

这是因为 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);

对于每个参数的类。

另外你不能在你的代码中声明一个“AnotherClass”类的变量,因为你不知道它在运行时是什么,所以你必须使用反射来处理它。

【讨论】:

以上是关于如何在java中动态实例化具有不同数量参数的java类?的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何在结构中定义类实例。类具有参数化构造函数[重复]

具有参数化模式名称并用于目标表中的 BULK INSERT 的动态游标

如何在R中的函数中有不同数量的具有默认值的参数?

具有动态共享内存的模板化 CUDA 内核

Activator.CreateInstance - 如何创建具有参数化构造函数的类的实例

如何在 UWP 中实例化具有构造函数的页面?