关于泛型:在Java中获取参数化类的实例

Getting an instance of a parameterized class in Java

本问题已经有最佳答案,请猛点这里访问。

我有这两个班

1
2
3
4
5
6
7
8
abstract class A
{
//some abstract methods and variables
}

class B<E extends A>
{
}

现在在B的方法中,我想得到一个E的虚拟实例。如何做到这一点?这个可以吗-

1
E temp = (E)(new Object());

我可以控制类定义,因此它们是灵活的。


您有两种解决方案:

  • 如果E有一个无参数的构造函数,您可以使用反射来构建一个。
  • 你可以做一个抽象的方法abstract E buildE();
  • 小精灵

    对于第一个解决方案,必须将类作为构造函数的参数传递:

    1
    2
    3
    4
    5
    6
    7
    class B<E extends A>{

      public B(Class<E> clazz){
        //Create instance of E:
        E e=clazz.newInstance();
      }
    }

    对于第二个解决方案,它意味着类B有一个抽象方法来构建对象(它或多或少相当于传递一个工厂):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class B<E extends A>{

      public abstract E buildE();

      private void foo(){
        E e = buildE();
        //Do generic stuff with E
      }

    }

    这样,如果创建B的子类,则需要实现此方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class B1 extends B<Bar>{

      //You are required to implement this method as it is abstract.
      public Bar buildE(){
        ..
      }

      private void anyMethod(){
        //call B.foo() which will use B1.buildE() to build a Bar
        super.foo();
      }

    }

    imho,第二种解决方案要干净得多。


    您需要将工厂对象(或实例)传递到EDOCX1的构造函数中(0)。无法指定泛型类型参数具有特定的构造函数,并且静态类型在运行时不可用。

    (你可以用E temp = (E)new A() { };来伪造一个显著的值,但这是很狡猾的。有些集合代码只对数组执行类似的操作。)


    您可以使用B中的反射来获取Class,然后获取所需的构造函数并调用newInstance

    1
    (Class<E>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]