相关文章推荐
坚强的甘蔗  ·  activemq无法启动-掘金·  11 月前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams public void invokeMyMethod() { Method s = this.getClass().getMethod("myMethod", Object[].class); Object[] ex = new Object[2]; ex[0] = "hi"; ex[1] = "there"; s.invoke(this, ex);

I'm getting the exception java.lang.IllegalArgumentException: wrong number of arguments. What's wrong?

It's clear that this isn't the real code, as there are typos (getClass -> getClass(), for example). Maybe the real code is different in some salient way? Ernest Friedman-Hill Mar 28, 2011 at 3:12 Ernest, I've edited to add the brackets for user679573. Other than that, the code was valid, so I felt this was a reasonable step. (Mainly commenting so that others don't misunderstand your comment.) Jon Bright Mar 28, 2011 at 11:03

You need to call the method like this:

s.invoke(this, new Object[]{new Object[]{"hi", "there"}});

(... or use the alternative in @Jon's answer.)

The reason your current code fails is to do with the way that varadic methods are implemented in Java. Essentially, T1 xxx(T2... args) is syntactic sugar for T1 xxx(T2[] args). And when you call the methods, xxx(arg1, arg2, arg3) is syntactic sugar for xxx(new T2[]{arg1, arg2, arg3}).

In this case, you are trying to call a varadic method using another varadic method with the same array basetype, and there are multiple possible interpretations of the code.

When there are two possible interpretations of a varadic call, Java assumes that you are trying to use the "unsugared" version of the call instead of the "sugared" version. Or to be more precise, the "sugared" interpretation is used if and only if:

  • the number of actual arguments is not equal to the number of formal parameters, or
  • the last actual argument is NOT assignment compatible with the (array) type of the last formal parameter.
  • If you are interested, this behaviour is specified in the JLS in section 15.12.4.2.

    So ... my solution works by forcing the non-varadic interpretation and explicitly constructing the required array. @Jon's solution works by forcing the correct varadic interpretation.

    The sugared version is also used if there are less actual arguments - then it creates an empty array. This would apply for s.invoke(this). – Paŭlo Ebermann Mar 28, 2011 at 8:56

    The problem here is with the variable arguments (the Object...) that Method.invoke takes.

    Changing this line

     s.invoke(this, ex);
    

    to this

     s.invoke(this, (Object)ex);
    

    will work.

    In the background, Object... is passed as an Object[]. Java's seeing your Object[] and choosing not to wrap it up in another Object[]. By casting to Object, it now just sees that and reverts to its normal wrap-it-up behaviour - the same as what other answers are doing manually.

    You can use dp4j command-line to answer your question:

        $ javac -cp ../dp4j-1.2-SNAPSHOT-jar-with-dependencies.jar -All -Averbose=true MyClass.java
    MyClass.java:7: Note: 
    public class MyClass {
    public MyClass() {
        super();
    public void myMethod(Object... args) {
        System.out.println("this is myMethod");
    @com.dp4j.Reflect()
    public void invokeMyMethod() throws java.lang.ClassNotFoundException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException, java.lang.IllegalArgumentException {
        final java.lang.reflect.Method myMethodWithArrayMethod = Class.forName("MyClass").getDeclaredMethod("myMethod", .java.lang.Object[].class);
        myMethodWithArrayMethod.setAccessible(true);
        myMethodWithArrayMethod.invoke(this, new .java.lang.Object[1][]{new .java.lang.Object[2][]{"hi", "there"}});
    public static void main(String... args) throws Exception {
        new MyClass().invokeMyMethod();
    public void invokeMyMethod() {
    $ java MyClass
    this is myMethod
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.