thisisshantzz
thisisshantzz

Reputation: 1097

Creating an instance of a parameterized class using an instance of java.lang.Class

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

Answers (2)

Tibrogargan
Tibrogargan

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

Louis Wasserman
Louis Wasserman

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

Related Questions