我在代码中使用了大量反射,其中一部分是反射性地动态创建类实例。我能够从正在解析的数据中得出所需的类型和参数。我将数据放入Object[]
中作为参数传递给Class.newinstance。我在做数据交叉引用程序时,某些参数是null
。这意味着我要获取两个数据集,并使用一个通用的Object
对其进行交叉引用(我现在要专门制作的那个是Salesrep
,但是此代码是动态的,因此可以更改)。这意味着在解析一个数据集时,创建该对象的某些参数应为null
,因为它们来自另一数据集。
不幸的是,每当我设置null
参数时,我都会得到Illegal Argument Exception
声明我有错误的参数数量。我检查了文档中的错误,并说只有在包装失败或参数数量错误时才抛出该错误。我尝试在整个Google上搜索,甚至在某些github仓库中都出现堆栈溢出,而我发现的只是有关method.invoke的一些问题,建议做类似的事情:
//add in non null args to objectArray
Object arg = null;
objectArray.add(arg)
//causes the exception here anyways.
Class.newinstance(objectArray)
我尝试过直接添加null而不包装它,但这也不起作用。请注意,这些构造函数不是空的也不是零参数,它们只有一个,并且我可以确认包括空值在内的参数数目等于所需数目。当参数不为null时,我还可以确认是否传递了正确的类型。我99%确信任何类型的参数都可以为空,或者至少我需要的参数类型确实可以为空(主要是基元和数组或其他集合)。我读过一些地方,当传递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
这是我的堆栈跟踪。首先是我在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
类的摘录。
答案 0 :(得分:1)
问题似乎在于您传递的是 $scope.changeDocument = function (applyFilter) {
if (applyFilter === true) {
//Here is where I cant access $scope
}
}
而不是数组:
List
您需要执行以下操作:
object_to_add = (ObjectImplementation) constructor.newInstance(argArrayOut);
// Passing a List ^^^^^^^^^^^
您没有在帖子中说object_to_add = (ObjectImplementation) constructor.newInstance(argArrayOut.toArray());
是argArrayOut
,但显然是一个,因为您在其上调用了List
方法。