Reputation: 198
I have a class C with an inner Class attribute:
public class C{
private Class<?> clazz;
public void setClazz(Class<?> c){
this.clazz = c;
}
public Class<?> getClazz(){
return clazz;
}
}
and I want do declare a method in another class so it's return type is that of C.clazz :
public class D{
public <T> T getInstance(C c){
//doesn't compile
//some reflective code to set T to c.getClazz?
return (c.getClazz.newInstance());
}
}
so, for example, getInstance(c), with c having clazz set to Class<B>
, would return me a new instance of B. Is there any way to do that with reflection?
Upvotes: 2
Views: 294
Reputation: 31724
class C<T>{
private final Class<T> clazz;
C(Class<T> clazz) {
this.clazz = clazz;
}
public Class<T> getClazz(){
return clazz;
}
}
class D{
public <T> T getInstance(C<T> t) throws IllegalAccessException, InstantiationException {
return t.getClazz().newInstance();
}
}
public static void main() throws Exception {
C<String> c = new C<>(String.class);
D d = new D();
String s = d.getInstance(c);
System.out.println("String = " + s);
}
This is also a classic way of storing generic type information. But I dont understand on why you would want getInstace
method inside D
. I would rather make it a static method inside C
.
You can adapt a similar tactic even it was an array with java.lang.reflect.Array.newInstance(t.getClazz(),10);
rather than just t.getClazz().newInstance()
There are even other ways to capture generic type information. Read this for more complex stuff.
Upvotes: 5
Reputation: 109547
public class C<T> {
private Class<T> clazz;
public void setClazz(Class<T> c){
this.clazz = c;
}
public Class<T> getClazz(){
return clazz;
}
}
public class D {
public <T> T getInstance(C<T> c){
//doesn't compile
//some reflective code to set T to c.getClazz?
return c.getClazz().newInstance();
}
public <T> T getInstance2(C c, Class<T> clazz){
//doesn't compile
//some reflective code to set T to c.getClazz?
return clazz.cast(c.getClazz().newInstance());
}
}
getInstance
needs a C with T param, or else getInstance2
would need a Class as parameter, and do an unsafe cast (you could add a check).
Upvotes: 0
Reputation: 22641
You need getClazz()
and a cast to T
:
public class D {
public <T> T getInstance(C c) throws InstantiationException, IllegalAccessException {
return (T)(c.getClazz().newInstance());
}
}
Upvotes: 0