Erdinç Taşkın
Erdinç Taşkın

Reputation: 1578

Generic Type Class initiating

We write a library that use generics, i am not sure how to create an instance of generic type. Shortly how to write create method?

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

Upvotes: 2

Views: 160

Answers (3)

Eugene
Eugene

Reputation: 120848

You should really consider @Tom Hawtin - tackline answer. It is the best and the approach is simply beautiful! All it takes is to add another factory implementation all the time, but it's quiet small payment.

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

Upvotes: 0

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147154

From a language point of view, there are no guarantees that V has a non-throwing, accessible, no-args constructor. The standard way to deal with this situation is to introduce an Abstract Factory as in, for instance, my answer here.

Upvotes: 2

ed_me
ed_me

Reputation: 3508

You cannot use new with a generic type; generics in java have type erasure. See http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.

There are a couple of dirty ways to acquire an instance of your generic class though; for example: -

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

Alternatively, you could create foo as a private member and do this without having to pass 'type.class' to the method whereby you pass the class in the constructor: -

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);

As others have said, you can create a factory that will do this for you. There's another stack overflow post that has further information Create instance of generic type in Java?

Upvotes: 0

Related Questions