2017-04-22 143 views
-1

对于编程的实际任务,我们给出一个例子.class文件。我们需要打印出所有采用1 x int输入和一些可打印输出的方法,然后允许用户通过命令行给出的一个输入来运行该方法。但是,当我尝试调用该方法时,会引发IllegalArgumentException。为什么在这里由Method.Invoke引发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. 
} 

由于一些故障安全检查,我已经做了以下内容:

  • 打印整数,以确认正确的扫描仪读取它。
  • 测试上的示例文件我知道的代码:

public class TestFile 
{ 
    public int testMethod(int testInt) 
    { 
     return 2*testInt; 
    } 
} 

命令行输出发生时:

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); 
+1

和哪一行是86 – strash

+0

Hey @ gen.Strash我已经评论过,在第一个代码块中,它是最后一行。 :) –

+2

很明显'inMethod'并不期待一个'Integer'(或'int')作为它的第一个参数。既然你没有告诉我们你如何获得'inMethod',我们无法真正帮助你。如果它真的引用了一个接受单个'Integer'或'int'的方法,它就可以工作。 –

回答

3

您的通话失败,因为你将null值传递给int参数。

invoke()的Javadoc说:

抛出IllegalArgumentException如果该方法是一个实例方法和指定对象参数不是类或接口声明底层方法的一个实例(或子类的或实施者);如果实际和形式参数的数量不同; 如果原始参数的展开转换失败;或者如果在可能的解包之后,通过方法调用转换不能将参数值转换为相应的形式参数类型。

因为转换nullint失败,你会得到IllegalArgumentException

你有一个null值的原因是你调用了错误的方法。的Integer.getInteger(String nm)的Javadoc说:

确定系统属性具有指定名称的整数值。

如果没有属性与指定的名称,如果指定名称为空或null,或者该属性不具备正确的数字格式,然后null返回

解决方案:你应该打电话Integer.valueOf(String s)

返回保存指定的String的值的Integer对象。参数被解释为表示一个带符号的十进制整数。

+0

但是,你怎么知道我不知道,谢谢! –

+0

现在完美运作,+1。 –

+2

就像一个注''Integer.parseInt'也应该正常工作。 – Tom