I'm new in JAVA and I'm trying to learn reflection. I want to get specific constructor (picking the example form here) from my class :
public class Example1 {
public Example1() {
}
public Example1(int i) {
}
public Example1(String s) {
System.out.println("using param = " + s);
}
public static void main(String[] args) throws Exception {
Class<?>[] paramTypes = String.class.getClasses();
Constructor<Example1> ctor = Example1.class.getConstructor(paramTypes);
ctor.newInstance("test");
}
}
I get NoSuchMethodException
when trying to instantiate ctor
What am I missing here?
Working example:
import java.lang.reflect.Constructor;
public class Test {
public Test(String str) {
System.out.println(str);
}
public Test(int a, int b) {
System.out.println("Sum is " + (a + b));
}
public static void main(String[] args) throws Exception {
Constructor<Test> constructorStr = Test.class.getConstructor(String.class);
constructorStr.newInstance("Hello, world!");
Constructor<Test> constructorInts = Test.class.getConstructor(int.class, int.class);
constructorInts.newInstance(2, 3);
}
}
Note that method getConstructor
actually doesn't take an array. It's defined like:
public Constructor<T> getConstructor(Class<?>... parameterTypes) {
... meaning that it accepts variable amount of arguments which should have been passed as I did. Passing an array is possible too, but it's not necessary.
What you've done originally was equivalent to:
Constructor<Test> constructor = Test.class.getConstructor(String.class.getClasses());
constructor.newInstance("Hello");
But, what does String.class.getClasses()
return? Good question! Lets go debug:
Class<?>[] classes = String.class.getClasses();
System.out.println(classes.length); // prints 0
There's a documentation about getClasses()
: https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getClasses. Check it and you'll find out the reason why it's so.
For the sake of completeness. The super-original-question (before edits) contained one more constructor - a non-parametric one:
import java.lang.reflect.Constructor;
public class Example1 {
public Example1() {
}
public Example1(String s) {
System.out.println("using param = " + s);
}
public static void main(String[] args) throws Exception {
Constructor<Example1> ctor = Example1.class.getConstructor(String.class.getClasses());
ctor.newInstance("test");
}
}
The problem which occurs here is IllegalArgumentException
being thrown. It's because even though String.class.getClasses()
returns an empty array, there actually is constructor which matches the criteria - a non-parametric constructor! It doesn't have any arguments and the array returned by String.class.getClasses()
doesn't contain anything too. This means that constructor is successfully found, but when trying to instantiate it using ctor.newInstance("test")
, it fails because the found constructor doesn't accept any arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With