使用null参数调用Class.newInstance导致IllegalArgumentException



我在做什么

我在代码中使用了大量的反射,其中一部分是动态地反射创建类实例。我能够从我正在解析的数据中获取所需的类型和参数。我将数据放入Object[]中,作为参数传递给Class.newinstance。有些参数是null,因为我正在制作数据交叉引用器。这意味着我将获取两个数据集,并使用一个通用的Object对它们进行交叉引用(我现在尝试具体制作的是Salesrep,但此代码是动态的,因此可以更改(。这意味着,在解析一个数据集时,创建该对象的一些参数应该是null,因为它们来自另一个数据集中。

问题和我尝试过的

不幸的是,每当我设置null参数时,我都会得到一个Illegal Argument Exception,说明我的参数数量不对。我已经检查了文档中的错误,它说只有当包装失败或实际存在错误数量的参数时才会抛出错误。我试着在谷歌上搜索,堆栈溢出,甚至一些github转发,我发现的只是一些关于方法的问题

//add in non null args to objectArray
Object arg = null;
objectArray.add(arg)
//causes the exception here anyways.
Class.newinstance(objectArray)

我试过直接添加null而不包装它,但这也不起作用。请注意,这些构造函数不是空的或零参数,它们只有一个,我可以确认包括null的参数数量等于所需数量。当参数不为null时,我还可以确认我正在传递正确的类型。我99%确信任何类型的参数都可以为null,或者至少我需要的参数类型确实可以为null(主要是基元和数组或其他集合(。我读过一些地方,当传递null时,它需要正确包装,并且它可能会将null误认为空对象数组参数。老实说,我只是不知道什么能奏效。我创建了一个try-catch块,它打印我传入的参数的数量和类型。它似乎每次都匹配,但它仍然会进入catch块。这是导致错误的我的代码:

代码以及如何理解

请注意:firstLineArray是我的数据中构造函数参数名称的String[]。并不是所有的构造函数参数都在其中一个数据集中,所以这段代码采用了实际的参数,并用可用数据填充它们。其他设置为null。这是使用两个映射完成的:argsWeHave将参数名称映射到数据,argsWeNeed将参数名称映像到其类型。这两个映射查看它们有哪些共同的参数名称,并将数据与其类型匹配,然后按构造函数需要的顺序将数据传递到argArrayOut

for (int j = 0; j < numberOfArgsNeeded; j++) {
//uses parameter name to match the argument string to its type in the constructor
//if the parameter name in the constructor isn't found among the param names we have data for OR
//if the parameter name in the header isn't found among the param names of the constructor, it adds a null element
//basically if there is an argument the constructor needs, and we have that argument by name.
if (argWeHave.containsKey(ParamNames[j]) && argWeNeed.containsKey(firstLineArray[i])){
//DONE fix where argWeNeed.get(firstLineArray[i]) returns null. Handle it gracefully rather than having NPE.
argArrayOut.add(stringToType(argArrayIn[i],argWeNeed.get(firstLineArray[i])));
i++;
}
//if there is no match set this argument to null
else{
//TODO wrap the null value or make it properly accept null as an arg to the object[] for newinstance.
Object arg = null;
argArrayOut.add(arg);
}
}
try {
//form the new instance with the properly formed argArrayOut.
object_to_add = (ObjectImplementation) constructor.newInstance(argArrayOut);
} 
//exception is thrown after the try. It always hits this catch block

这是我的Stack Trace。首先是我在catch块中打印到系统的内容:

Class type: Sales_Rep_Data.SalesRep
number of parameters in constructor: 5
number of arguments passed to constructor: 5
Types needed in constructor
class java.lang.String , class java.lang.String , class java.lang.String , 
class java.lang.String , class java.util.ArrayList
Types provided to constructor
class java.lang.String , class java.lang.String , class java.lang.String , 
null , null 

然后是实际的堆叠竞争:

java.lang.IllegalArgumentException: wrong number of arguments
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
at Sales_Rep_Data.ObjectFactory.getObjectImpl(ObjectFactory.java:79)
at Sales_Rep_Data.SalesRepbyId.Parse(SalesRepbyId.java:27)
at Sales_Rep_Data.Data_Parser.main(Data_Parser.java:45)

根据我打印的内容,您可以看到,我有所需的编号和类型。我无法理解为什么会出现这种错误。这一定是某种远程包装要求,或者是我觉得很傻的事情。欢迎提出任何代码可读性建议。这段代码本身是不可运行的,它需要很多其他代码,这只是我的ObjectFactory类中的一个片段。

问题似乎是您传递的是List而不是数组:

object_to_add = (ObjectImplementation) constructor.newInstance(argArrayOut);
//                                              Passing a List ^^^^^^^^^^^

你需要这样做:

object_to_add = (ObjectImplementation) constructor.newInstance(argArrayOut.toArray());

你在帖子中没有说argArrayOutList,但它显然是一个,因为你在上面调用了add方法

相关内容

  • 没有找到相关文章

最新更新