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

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

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

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


当前回答

考虑一种更函数化的方法:与其凭空创建一些E(这显然是一种代码味道),不如传递一个知道如何创建E的函数。

E createContents(Callable<E> makeone) {
     return makeone.call(); // most simple case clearly not that useful
}

其他回答

注意,kotlin中的泛型类型可能没有默认构造函数。

 implementation("org.objenesis","objenesis", "3.2")

    val fooType = Foo::class.java
    var instance: T = try {
        fooType.newInstance()
    } catch (e: InstantiationException) {
//            Use Objenesis because the fooType class has not a default constructor
        val objenesis: Objenesis = ObjenesisStd()
        objenesis.newInstance(fooType)
    }

没有默认构造函数 Objenesis

正如你说的,你不能真正做到这一点,因为类型擦除。你可以使用反射来实现,但这需要大量的代码和错误处理。

你可以使用:

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

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

你可以通过下面的代码片段来实现这一点:

import java.lang.reflect.ParameterizedType;

public class SomeContainer<E> {
   E createContents() throws InstantiationException, IllegalAccessException {
      ParameterizedType genericSuperclass = (ParameterizedType)
         getClass().getGenericSuperclass();
      @SuppressWarnings("unchecked")
      Class<E> clazz = (Class<E>)
         genericSuperclass.getActualTypeArguments()[0];
      return clazz.newInstance();
   }
   public static void main( String[] args ) throws Throwable {
      SomeContainer< Long > scl = new SomeContainer<>();
      Long l = scl.createContents();
      System.out.println( l );
   }
}

正如您所提到的,您不能从泛型中获得实例。在我看来,你必须改变设计,使用FACTORY METHOD设计模式。通过这种方式,你不需要你的类或方法是泛型:

class abstract SomeContainer{
    Parent execute(){
        return method1();
    }
    
    abstract Parent method1();
}


class Child1 extends Parent{
    Parent method1(){
        return new Parent();
    } 
} 

class Child2 extends Parent{
    Parent method1(){
        return new Child2();
    } 
}