Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating object of type parameter

I have got a template class as follows:

class MyClass<T> {     T field;     public void myMethod()     {        field = new T(); // gives compiler error     } } 

How do I create a new instance of T in my class?

like image 306
Mercurious Avatar asked Nov 18 '08 20:11

Mercurious


1 Answers

After type erasure, all that is known about T is that it is some subclass of Object. You need to specify some factory to create instances of T.

One approach could use a Supplier<T>:

class MyClass<T> {    private final Supplier<? extends T> ctor;    private T field;    MyClass(Supplier<? extends T> ctor) {     this.ctor = Objects.requireNonNull(ctor);   }    public void myMethod() {     field = ctor.get();   }  } 

Usage might look like this:

MyClass<StringBuilder> it = new MyClass<>(StringBuilder::new); 

Alternatively, you can provide a Class<T> object, and then use reflection.

class MyClass<T> {    private final Constructor<? extends T> ctor;    private T field;    MyClass(Class<? extends T> impl) throws NoSuchMethodException {     this.ctor = impl.getConstructor();   }    public void myMethod() throws Exception {     field = ctor.newInstance();   }  } 
like image 102
erickson Avatar answered Sep 24 '22 17:09

erickson