通用类型类启动

时间:2013-04-15 07:46:52

标签: java generics

我们编写了一个使用泛型的库,我不知道如何创建泛型类型的实例。简而言之,如何编写create方法?

public class Lib<V extends Base> {

    private HashMap<Integer, V> map = new HashMap<Integer, V>();    

    public V get(int key) {
        return map.get(key);
    }

    public void add(int key, V value) {
        map.put(key, value);
    }

    public void create(int key) {
        // V v = new V();  // ?? How to implement this line
        // add(key++, v);
    }
}

3 个答案:

答案 0 :(得分:2)

从语言的角度来看,不能保证V具有非投掷,可访问,无参数的构造函数。处理这种情况的标准方法是引入一个抽象工厂,例如,my answer here

答案 1 :(得分:0)

您不能将new用于泛型类型; java中的泛型有类型擦除。见http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

  

类型擦除确保不为参数化类型创建新类;因此,泛型不会产生运行时开销。

虽然有一些肮脏的方法来获取你的泛型类的实例;例如: -

void create(Class<V> foo)
{
    foo.newInstance(); // Create a new instance of generic type V
}

或者,你可以创建foo作为私有成员,并且不必将'type.class'传递给你在构造函数中传递类的方法: -

class bar<V>
{
    private Class<V> baz;

    private V qux;

    public bar(Class<V> foo)
    {
        baz = foo;
    }

    void create()
    {
        qux = baz.newInstance();
    }
}

bar<Integer> quxx = new bar<Integer>(Integer.class);

正如其他人所说,你可以创建一个为你做这件事的工厂。还有另一个堆栈溢出帖子,其中包含更多信息Create instance of generic type in Java?

答案 2 :(得分:0)

你应该考虑@Tom Hawtin - 强调答案。这是最好的,方法很简单!所需要的只是一直添加另一个工厂实施,但这是一个安静的小额支付。

  public class InstanceOfGenericClass {
      public static void main(String[] args) {
          new GenericClass<VPassed>(new FactoryImpl()).createInstance();
      }
  }

// --------------------------------------------- ---------------

 class GenericClass<V>{

     private final Factory<V> factory;
     public GenericClass(Factory<V> factory){
         this.factory = factory;
     }

     V createInstance(){
         return factory.create();
     }
 }

// --------------------------------------------- ----------------

interface Factory<V>{
V create();

}

// --------------------------------------------- ----------------

 class FactoryImpl implements Factory<VPassed>{
     @Override
     public VPassed create() {
         return new VPassed();
     }
 }

// --------------------------------------------- -----------------

class VPassed{}