2013-04-15 2 views
2

Мы пишем библиотеку, которая использует generics, я не уверен, как создать экземпляр родового типа. Вскоре, как написать метод создания?Generic Type Class initialating

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); 
    } 
} 
+0

Что вы хотите создать? – aymankoo

+0

Это невозможно, – BlackJoker

+0

(Возможно, вы захотите удалить это статическое поле.) (Edit: О, я сделаю это.) –

ответ

0

Вы не можете использовать новые с общим типом; У дженериков в java есть стирание типа. См. http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Тип erasure гарантирует, что для параметризованных типов не создаются новые классы; следовательно, дженерики не накладывают на них лишние расходы.

Существует несколько грязных способов получить экземпляр вашего общего класса; например: -

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?

+0

FFS, не используйте отражение для этого. (К счастью, Java достаточно хорош, чтобы предотвратить компиляцию кода. –

+0

Нужна ли голосование? Я уже предложил, чтобы фабрика могла быть использована для этого и предоставила ссылку на вопрос, на который был проголосован ответ для разрешения это использование фабрики. – chrisw

+1

Предлагая использовать отражение для этого, это опасно. Да, он заслуживает понижения. –

2

С языковой точки зрения нет никаких гарантий, что у V есть конструктор без доступа, доступный, без аргументов. Стандартный способ справиться с этой ситуацией - ввести абстрактную фабрику, например, в my answer here.

+0

@TomHawtintackline ваш подход просто потрясающий! Thx для предложения. – Eugene

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{}