有可能在Java中创建泛型类型的实例吗?我在想,根据我所看到的,答案是否定的(由于类型擦除),但如果有人能看到我遗漏的东西,我会很感兴趣:

class SomeContainer<E>
{
    E createContents()
    {
        return what???
    }
}

编辑:事实证明,超级类型令牌可以用来解决我的问题,但它需要大量基于反射的代码,如下面的一些答案所示。

我将把这个问题放一段时间,看看是否有人提出了与Ian Robertson的Artima文章截然不同的东西。


当前回答

这是我想到的一个选择,可能会有帮助:

public static class Container<E> {
    private Class<E> clazz;

    public Container(Class<E> clazz) {
        this.clazz = clazz;
    }

    public E createContents() throws Exception {
        return clazz.newInstance();
    }
}

EDIT:你也可以使用这个构造函数(但它需要一个E的实例):

@SuppressWarnings("unchecked")
public Container(E instance) {
    this.clazz = (Class<E>) instance.getClass();
}

其他回答

使用TypeToken<T>类:

public class MyClass<T> {
    public T doSomething() {
        return (T) new TypeToken<T>(){}.getRawType().newInstance();
    }
}

你需要某种抽象工厂来把责任传递给:

interface Factory<E> {
    E create();
}

class SomeContainer<E> {
    private final Factory<E> factory;
    SomeContainer(Factory<E> factory) {
        this.factory = factory;
    }
    E createContents() {
        return factory.create();
    }
}

我不知道这是否有帮助,但当您子类化(包括匿名)泛型类型时,类型信息可以通过反射获得。例如,

public abstract class Foo<E> {

  public E instance;  

  public Foo() throws Exception {
    instance = ((Class)((ParameterizedType)this.getClass().
       getGenericSuperclass()).getActualTypeArguments()[0]).newInstance();
    ...
  }

}

所以,当你子类化Foo时,你得到Bar的一个实例,例如,

// notice that this in anonymous subclass of Foo
assert( new Foo<Bar>() {}.instance instanceof Bar );

但是工作量很大,而且只适用于子类。不过也很方便。

你可以使用:

Class.forName(String).getConstructor(arguments types).newInstance(arguments)

但是您需要提供确切的类名,包括包,例如。java.io.FileInputStream。我使用它来创建数学表达式解析器。

我受到了Ira的启发,并对其稍加修改。

abstract class SomeContainer<E>
{
    protected E createContents() {
        throw new NotImplementedException();
    }

    public void doWork(){
        E obj = createContents();
        // Do the work with E 
     }
}

class BlackContainer extends SomeContainer<Black>{
    // this method is optional to implement in case you need it
    protected Black createContents() {
        return new Black();
    }
}

如果你需要E实例,你可以在你的派生类中实现createContents方法(或者不实现它,以防你不需要它)。