Can't invoke method with varargs parameters with reflection - NoSuchMethodException

倖福魔咒の 提交于 2019-12-29 08:13:03

问题


I'm trying to use reflection to invoke method with varargs parameters.

And caught NoSuchMethodException. I couldn't figure out what is wrong here.

Code:

public class ReflectionTest {

    public ReflectionTest() {   }

    private void varargMethod(String string, Integer ... var) {

        System.out.println("vargarMethod() called");
        System.out.println(string + " Number of args: " + var.length
                + "\nContents");

        for (int i = 0; i < var.length; i++) {
            System.out.printf(" args %d: %d", i, var[i]);
            //System.out.println(" args " + i + ": " + var[i]);
        }

        System.out.println();
    }

    public static void main(String[] args) throws Exception {

        Class[] parameterTypes = new Class[] { String.class, int.class, int.class, int.class };

        //System.out.println(Arrays.toString(parameterTypes));

        Method varMeth = test.getClass().getDeclaredMethod("varargMethod", parameterTypes);
        System.out.println("varMeth" + varMeth);

        Object[] arguments = new Object[] { new String("my perfect string"),
                new Integer(10), new Integer(100), new Integer(47) };

        varMeth.invoke(test, arguments);

It throws exactly:

java.lang.NoSuchMethodException: ReflectionTest.varargMethod(java.lang.String, int, int, int)

  • How to solve this trouble?

回答1:


The parameter types should be Integer[].class for a varargs as varargs expression specifies that the parameter is a variable array parameter. So a correct way is:

Class[] parameterTypes = new Class[] { String.class, Integer[].class };

//System.out.println(Arrays.toString(parameterTypes));
ReflectionTest test = new ReflectionTest();
Method varMeth = test.getClass().getDeclaredMethod("varargMethod", 
                                                      parameterTypes);
System.out.println("varMeth" + varMeth);

Object[] arguments = new Object[] { new String("my perfect string"),
                                    new Integer[]{10, 100, 47}
                                  };

varMeth.invoke(test, arguments);



回答2:


If you compile your .java file and then decompile your .class file, you will see this declaration of the method:

private transient void varargMethod(String string, Integer var[])

So here is your code fixed.

import java.lang.reflect.Method;

public class ReflectionTest {

    public ReflectionTest() {   }

    private void varargMethod(String string, Integer ... var) {

        System.out.println("vargarMethod() called");
        System.out.println(string + " Number of args: " + var.length
                + "\nContents");

        for (int i = 0; i < var.length; i++) {
            System.out.printf(" args %d: %d", i, var[i]);
            //System.out.println(" args " + i + ": " + var[i]);
        }

        System.out.println();
    }

    public static void main(String[] args) throws Exception {

        ReflectionTest test = new ReflectionTest(); 
        Class[] parameterTypes = new Class[] { String.class, Integer[].class };

        //System.out.println(Arrays.toString(parameterTypes));

        Method varMeth = test.getClass().getDeclaredMethod("varargMethod", parameterTypes);
        System.out.println("varMeth" + varMeth);

        Object[] arguments = new Object[] { new String("my perfect string"),
                new Integer[] { new Integer(10), new Integer(100), new Integer(47) } };

        varMeth.invoke(test, arguments);
    }
}



回答3:


Here's the fixed code, with minimal changes. Comments inline for changes:

import java.lang.reflect.Method;

public class ReflectionTest {

    public ReflectionTest() {}

    private void varargMethod(String string, Integer... var) {

        System.out.println("vargarMethod() called");
        System.out.println(string + " Number of args: " + var.length + "\nContents:");

        for (int i = 0; i < var.length; i++) {
            System.out.printf(" args %d: %d", i, var[i]);
        }

        System.out.println();
    }

    public static void main(String[] args) throws Exception {

        Class[] parameterTypes = new Class[] {
                                        String.class,
                                        Integer[].class // use array to represent varargs
                                      };

        //System.out.println(Arrays.toString(parameterTypes));
        ReflectionTest test = new ReflectionTest();
        Method varMeth = test.getClass().getDeclaredMethod("varargMethod", parameterTypes);
        System.out.println("varMeth" + varMeth);

        Object[] arguments = new Object[]{
                                    "my perfect string",
                                    new Integer[]{10, 100, 47} // again use array for varargs
                                  };

        varMeth.invoke(test, arguments);
    }

}


来源:https://stackoverflow.com/questions/20440839/cant-invoke-method-with-varargs-parameters-with-reflection-nosuchmethodexcept

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!