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

时间:2014-06-08 07:53:25

标签: java generics abstract-class

嘿,伙计们希望你能帮助我。

基本上我正在创建一个泛型类型的函数,泛型类型是我需要实例化的抽象类型。此代码将更清楚地解释它:

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


}

基本上我想强制执行&#34; T扩展AbstractRow但不是抽象本身&#34;

我意识到你无法实例化抽象类,所以我想要一个关于变通方法或其他方法的建议,这些方法可以让我模仿创建泛型类型对象的行为。 提前致谢

2 个答案:

答案 0 :(得分:4)

据我所知,有两种方法可以做到这一点:

  1. 向抽象泛型类添加Class<T> type字段,并通过构造函数(或其他方法)设置它。然后,您可以调用type.newInstance()来创建对象。
  2. 使用Factory<T>方法创建工厂接口T create(),并通过构造函数(或其他方法)将其设置为抽象类的字段。在创建泛型类的具体实例时,您还必须传递所述工厂的具体实现。
  3. 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();
    

答案 1 :(得分:3)

您的主要问题不是您正在使用抽象类 - 在这种情况下,评论中发布的建议会很有用。更大的问题是你试图直接实例化一个泛型类型(阅读:new T()) - 简单地说,由于type erasure,你不能用Java做。

那就是说,总有一种解决方法:

/**@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"
  }
}