为什么调用调用方法(JAVA)时出现“参数数量错误”异​​常

时间:2018-10-18 22:03:16

标签: java

我正在尝试使用Java中的反射来调用方法,但是当我调用invoke方法时,会出现异常。这是我的代码:

public void start() {
    try {   
        ServerSocket server = new ServerSocket(port);

        while(true) {
            Socket s = server.accept();

            ObjectInputStream in = new ObjectInputStream(s.getInputStream());

            Class<?> myClass = Class.forName(vmi.getClass().toString().split(" ")[1]);          

            ArrayList<Object> array = new ArrayList();

            Constructor<?> cons = myClass.getConstructor(new Class<?>[] {});    


            String method = null;
            for(Method m : myClass.getMethods()) {
                method = in.readObject().toString();

                if(m.getName().equals(method)) {

                    Type return_type = m.getGenericReturnType();

                    for(Type types: m.getGenericParameterTypes()) {
                        array.add(in.readObject());
                    }
                    System.out.println(return_type);
                    if (return_type.toString().equals("void")) {                            
                         m.invoke(vmi, (Object)array);
                    }                       
                    break;
                }
            }   

        }
    } catch (IOException | ClassNotFoundException | NoSuchMethodException 
            | SecurityException | IllegalAccessException 
            | IllegalArgumentException | InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

        System.out.println("Skeleton Exception "+ e.toString());
    }
}

这是例外:

  

java.lang.IllegalArgumentException:参数数量错误

我还尝试使用空对象调用该方法,并且异常继续

m.invoke(vmi, new Object(), new Object());

顺便说一下,变量 vmi port 在构造函数中初始化。

1 个答案:

答案 0 :(得分:1)

Method.invoke方法的签名是:

public Object invoke(Object obj, Object... args)

这是语法糖(如果您不通过varargs):

public Object invoke(Object obj, Object[] args)

但是,您正在传递(Object,Object)->这将把第二个对象作为varargs的单个参数,因此编译器会将您的调用转换为m.invoke(vmi, new Object[] { array })

使代码复杂化的事实是,您有一个名为array的变量,但其类型实际上是ArrayList,它不是数组。

您可以将代码更改为:

m.invoke(vmi, array.toArray());

这会将您的参数作为整个varargs参数args传递,而不是作为varargs数组中的单个元素传递。