使用泛型类型实例化抽象类的对象

6
我正在创建一个具有通用类型的函数,该通用类型是一个抽象类型,我需要实例化它。以下代码将更清楚地解释这一点:
public <T extends AbstractRow> foo(){//no I did not actually name the function foo
    ArrayList<T> arr=new ArrayList<T>();
    arr.add(new T(...)); //cant instantiate objects of abstract class


}

基本上我想强制执行“T extends AbstractRow但它本身不是抽象的”。

我意识到您无法实例化抽象类,因此我想建议一种解决方法或其他方法,以允许我模仿创建泛型类型对象的行为。


除非你实现了所有的抽象方法,否则无法实例化一个抽象类。 - user184994
我明白了。我需要一个“变通方法”或一些想法,以使这样的实现能够工作,其中我需要实例化泛型类型的对象。 - Ahmed-Anas
各位,你们从什么时候开始可以直接实例化泛型类型了? - drew moore
@drewmore 如果你有一个非抽象的AbstractRow子类,你可以这样做:T t = (T) new SubClassName(); - Christian Tapia
1
@Christian 是的,你可以这样做,但那不是直接实例化一个泛型类型 - 它是实例化一个具体类型并将其强制转换为泛型类型。 - drew moore
2个回答

4
据我所知,有两种方法可以实现这个:
  1. 在抽象泛型类中添加一个 Class<T> type 字段,并通过构造函数(或其他方法)设置它。然后,您可以调用 type.newInstance() 来创建对象。
  2. 创建一个工厂接口 Factory<T>,其中包含一个 T create() 方法,并通过构造函数(或其他方法)将其设置为抽象类的字段。在创建泛型类的具体实例时,还必须传递所述工厂的具体实现。
import java.util.ArrayList;
import java.util.List;

public class Generic<T> {
    private Factory<T> factory;

    public Generic(Factory<T> factory) {
        this.factory = factory;
    }

    public void foo() {
        List<T> list = new ArrayList<>();

        list.add(factory.create());
    }
}

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

使用方法:

Generic<Bar> concrete = new Generic<>(new Factory<Bar>() {
    @Override
    public Bar create() {
        return new Bar();
    }
});

concrete.foo();

3
你的主要问题不在于你正在使用抽象类 - 在这种情况下,评论中发布的建议将非常有用。更大的问题是你试图直接实例化一个泛型类型(即:new T())- 简单来说,在Java中你不能这样做,因为type erasure
话虽如此,总会有解决方法:
/**@param clazz the subclass you want to instantiate */
public <T extends AbstractRow> foo(Class<T> clazz) { 
    ArrayList<T> arr = new ArrayList<T>();
    arr.add(clazz.newInstance); //instantiate new instance of given subclass
}

使用方法:

abstract class Test1  {} 
class Test2 extends Test1{ }

class Test<T> {
   public static <T extends Test1> T foo(Class<T> clazz) {
     T toReturn = null;
     try{ toReturn = clazz.newInstance(); } catch (Exception e) { };
     return toReturn ;
  }

  public static void main(String[] args) {
    Test1 t1 = t.foo(test2.class);
    System.out.println(t1.getClass()); //prints "class pkgname.test2"
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接