Reputation: 333
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
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
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