zoro
zoro

Reputation: 333

reflection newinstance constructor java wrong number of arguments

I am learning Reflection in Java, and trying to make an example of Constructor. But there is a problem: "wrong number of arguments". Searching through google and stackoverflow, I cannot find the same problem as I am currently facing. can anyone please help me to understand the problem, thank you so much. This is my codes:

    public static void main(String[] args) {
    PrintClass f = new PrintClass();
    Class cl = f.getClass();
    Constructor<?> constructor[] = cl.getDeclaredConstructors(); // cl.getDeclaredConstructors() also won't work...

    f.field1 = 3;
    PrintClass p1 = null;
    PrintClass p2 = null;

    try {
        p1 = (PrintClass) constructor[0].newInstance(); // constructor[0].newInstance((Object[])args) also won't work...
        p2 = (PrintClass) constructor[1].newInstance("this is not PrintClass-------");

        p1.print();
        p2.print();

    } catch (InstantiationException | IllegalAccessException
            | IllegalArgumentException | InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    }
}

class PrintClass {
String s = "this is PrintClass...";
int field1;

public PrintClass(String s) {
    this.s = s;
}

public PrintClass() {
}

public void print() {
    System.out.println(s);
}

}

and this is the error

java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at reflection.MainClass.main(MainClass.java:18)

Again, thank you so much for helping me understand the problem. :)

Upvotes: 1

Views: 5556

Answers (2)

shreeramaute
shreeramaute

Reputation: 412

the "wrong number of arguments" error on call of newInstance() appears till Java 10, which is resolved in Java 11 onwards.

@JBNizet solution is right, I would like to add to it, you can get array of constructors, loop through each constructor, add a conditional check for parameter counts as per your need and do the respective configurations as follows:

Constructor<?>[] constructors = cl.getDeclaredConstructors();
try {
      for( Constructor construct : constructors){
          if (construct.getParameterCount() == 0) {
           p1 = (PrintClass) construct.newInstance(null); 
          }
          p2 = (PrintClass) construct.newInstance("this is not PrintClass");
      }
      p1.print();
      p2.print();
    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
    }

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691715

You're calling the first of the two constructors without argument. But how can you be sure that the first constructor in the array is the one without argument, and not the one expecting a String?

You can't, because the javadoc says:

The elements in the array returned are not sorted and are not in any particular order.

If you want a reference to the no-argument constructor of the class, you should call

cl.getDeclaredConstructor();

If you want a reference to the constructor taking a STring as argument, you should call

cl.getDeclaredConstructor(String.class);

Upvotes: 5

Related Questions