Reputation: 1097
Lets say that I have a parameterized class
public class<K> MyClass {
private K val;
public K getVal() { return val; }
public void setVal(K val) { this.val = val; }
}
My objective is to be able to create an instance of this class using a parameter that I pass as an argument. This parameter is of type java.lang.Class. Something along the lines of
public void createInstance(Class<?> klass) {
MyClass<klass> k = new MyKlass<>();
}
Now, I know that this is incorrect. I cannot pass the variable klass as a parameter to MyClass. But is it possible create an instance of MyClass that is parameterized with the Class represented by the klass variable?
Upvotes: 2
Views: 217
Reputation: 4603
Expounding on Louis Wasserman's answer:
You could create a meta-factory to spit out instances of class factories:
public class MyClassFactory<K> {
final Class<K> klass;
protected MyClassFactory(final Class<K> clazz) {
klass = clazz;
}
protected K create() throws InstantiationException, IllegalAccessException {
return klass.newInstance();
}
public static <K> MyClassFactory<K> createFactory(final Class<K> clazz) throws InstantiationException, IllegalAccessException {
return new MyClassFactory(clazz);
}
}
And then call it something like this:
MyClassFactory<? extends MyClass> myClassFactory = MyClassFactory.createFactory((new MyClass<Foo>()).getClass());
MyClass<Foo> myFooClass = myClassFactory.create();
Foo foo = new Foo();
myFooClass.setVal(foo);
But you'll notice that the factories produced give you <? extends MyClass>
, not a MyClass<Foo>
, so you can also do this (with the same factory):
MyClass<Baz> myBazClass = myClassFactory.create();
Baz baz = new Baz();
myBazClass.setVal(baz);
System.out.println(myBazClass.getVal());
And unfortunately also this:
MyClass fubar = myClassFactory.create();
Object obj = new SomeArbitraryObject();
fubar.setVal(obj);
System.out.println(fubar.getVal());
Upvotes: 1
Reputation: 198341
is it possible create an instance of MyClass that is parameterized with the Class represented by the klass variable?
No.
The reason is, as far as your program is concerned when it runs, there is no difference between a Foo<Bar>
and a Foo<Baz>
.
Create it raw and cast it. Any other solution will be equivalent to that.
Upvotes: 2