Java 为什么方法.Invoke在这里抛出IllegalArgumentException?
对于编程实际任务,我们给出了一个示例.class文件。我们需要打印出所有接受1 x int输入和一些可打印输出的方法,然后允许用户使用命令行给定的一个输入运行该方法。但是,当我尝试调用该方法时,会抛出一个IllegalArgumentException 引发异常的代码:Java 为什么方法.Invoke在这里抛出IllegalArgumentException?,java,methods,reflection,instance,illegalargumentexception,Java,Methods,Reflection,Instance,Illegalargumentexception,对于编程实际任务,我们给出了一个示例.class文件。我们需要打印出所有接受1 x int输入和一些可打印输出的方法,然后允许用户使用命令行给定的一个输入运行该方法。但是,当我尝试调用该方法时,会抛出一个IllegalArgumentException 引发异常的代码: // Request the user enter an integer and run the requested method. private static void methodInvoke(Method inMetho
// Request the user enter an integer and run the requested method.
private static void methodInvoke(Method inMethod, Class methodClass, Scanner scanner) throws
NumberFormatException,IllegalAccessException,InvocationTargetException,InstantiationException,ClassNotFoundException
{
Integer userNumber = 0;
Object methodObject = methodClass.newInstance();
System.out.println(inMethod.toString()); // Test to confirm printing the correct method.
System.out.println("Enter a number to supply to: '" + inMethod.toString() + ":");
userNumber = Integer.getInteger(scanner.nextLine());
System.out.println(inMethod.invoke(methodObject, userNumber)); // Throws IllegalArgumentException here.
}
作为一些故障保护检查,我已完成以下工作:
- 打印整数以确认扫描仪正确读取
- 在我知道其代码的示例文件上进行了测试:
发生时的命令行输出:
Enter a number to supply to: 'public int TestFile.testMethod(int):
1
Error: Invalid argument.
java.lang.IllegalArgumentException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at MethodMetrics.methodInvoke(MethodMetrics.java:79)
at MethodMetrics.main(MethodMetrics.java:29)
任何关于原因的想法都将不胜感激。我是否遗漏了一些明显的东西?:)
编辑:以下是选择方法的代码:
private static Method[] getIntMethods(Class classToTest) throws NullPointerException
{
int counter = 0;
Method[] allFoundMethods = classToTest.getDeclaredMethods(); // Unnecessary to check for SecurityException here
Method[] returnMethods = new Method[allFoundMethods.length];
if(returnMethods.length > 0) // Only bother if the class has methods.
{
for(Method mTest : allFoundMethods)
{
if(mTest.getParameterTypes().length == 1)
{
if(mTest.getParameterTypes()[0].getName().equals("int"))
{
returnMethods[counter++] = mTest;
}
}
}
returnMethods = Arrays.copyOf(returnMethods, counter);
}
return returnMethods;
}
其中,从主方法调用“methodInvoke”:
System.out.println("Select a method with the method index from above: '(0) to (n-1)':");
selectedMethod = scanner.nextLine();
methodInvoke(foundMethods[Integer.parseInt(selectedMethod)], scanner);
调用失败,因为您正在将
null
值传递给int
参数
Javadoc说:
如果方法是实例方法,且指定的对象参数不是声明基础方法(或其子类或实现者)的类或接口的实例,则抛出IllegalArgumentException
;如果实际参数和形式参数的数量不同如果原语参数的展开转换失败;或者,如果在可能的展开之后,无法通过方法调用转换将参数值转换为相应的形式参数类型
由于将null
转换为int
失败,您将获得IllegalArgumentException
之所以有null
值,是因为调用了错误的方法。Javadoc说:
确定具有指定名称的系统属性的整数值
如果没有具有指定名称的属性,如果指定名称为空或null
,或者属性没有正确的数字格式,则返回null
解决方案:您应该打电话
返回一个整数
对象,该对象包含指定的字符串的值
。该参数被解释为表示有符号十进制整数
哪一行是
inMethod
显然不需要整数(或int
)作为其第一个参数。由于您尚未向我们展示如何在方法中获得,我们无法真正提供帮助。如果它确实引用了一个接受单个Integer
或int
的方法,它会工作。与其打印inMethod.getName()+“(int)”
,不如尝试打印inMethod
本身,它将打印完整的方法签名,我们都知道您试图调用什么方法。为什么要执行Class.forName(inMethod.getDeclaringClass().getName())
,而inMethod.getDeclaringClass()
已经是您要查找的Class
对象了?--如果不存在参数/默认构造函数,newInstance()
就会失败,为什么要打印构造函数呢?下面的运行很好:我不知道你是怎么知道的,谢谢!现在可以很好地工作,+1。就像注释整数一样。parseInt
也可以很好地工作。
System.out.println("Select a method with the method index from above: '(0) to (n-1)':");
selectedMethod = scanner.nextLine();
methodInvoke(foundMethods[Integer.parseInt(selectedMethod)], scanner);