Reputation: 723
I want to create an instance of a class via reflection, and I know the given constructor parameters are compatible with the constructor. Though I do not have the formal parameter types of the constructor.
I know I can go through all constructors of the class to do this, but is there a more direct way in standard Java 8 API?
Upvotes: 1
Views: 133
Reputation: 3809
If with Java 8 API
means using streams you can do:
public static <T> T createInstance(Class<T> clz, Object... params) throws Exception {
Class<?>[] c = Arrays
.stream(params)
.map(Object::getClass)
.toArray(Class<?>[]::new);
return clz.getConstructor(c).newInstance(params);
}
Test:
public static void main(String... args) throws Exception {
String s = createInstance(String.class, (Object) new char[] {'h', 'e', 'l', 'l', 'o'});
System.out.println(s);
}
Output:
hello
Basically the same as the other answer though, maybe a bit more elegant...
My function will fail for primitive types, as I can't get Integer.TYPE
from a generic type.
Upvotes: 1
Reputation: 45339
If the runtime classes of your parametes match exactly the declared type of constructor parameters, you can build the corresponding array of Class
instances, then look up the constructor:
public static void main(String[] args) throws Exception {
Object[] params = new Object[] {Integer.valueOf(2), "name"};
Class<?> cls[] = new Class<?>[params.length];
List<Class<? extends Object>> classes =
Arrays.asList(params).stream().map(p -> p.getClass())
.collect(Collectors.toList());
for(int i = 0; i < params.length; i++) {
cls[i] = classes.get(i);
}
Person.class.getConstructor(cls)
.newInstance(params);
}
That would work with a constructor declared as in this example:
class Person {
public Person(Integer i, String name) {
System.out.println("i: " + i + " name: " + name);
}
}
That prints:
i: 2 name: name
Upvotes: 3