Java 为什么方法.Invoke在这里抛出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

对于编程实际任务,我们给出了一个示例.class文件。我们需要打印出所有接受1 x int输入和一些可打印输出的方法,然后允许用户使用命令行给定的一个输入运行该方法。但是,当我尝试调用该方法时,会抛出一个IllegalArgumentException

引发异常的代码:

// 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);