Instantiating object of type parameter

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();
  }

}

Leave a Comment