开发者

Java generics - getting the type

Duplicate: Instantiating generics type in java

Hi! I'm a c# guy giving Java a try .. so how would I do the following in java.

in C#

public T create_an_instance_of<T>(){
  T instance = default (T);
 // here's usually some factory to cr开发者_如何转开发eate the implementation
   instance =  some_factory.build<T>();
 // or even..
   instance = some_factory.build(typeOf(T) );

 return instance;
}


Java's generics are based on type erasure. That allows them to be downwards-compatible, but means that you cannot use the type parameter itself, because it does not exist at runtime.

The closest thing you can do is this:

public <T> T create_an_instance_of(Class<T> c){
    return c.newInstance(); // or use constructors via reflection
}


You can't do that in Java because generics are non-reified. You can use what are called "type tokens", but it has limitations.

 static <T> T construct(Class<T> klazz) {
     try {
        return klazz.newInstance();
     } catch (InstantiationException e) {
        return null;
     } catch (IllegalAccessException e) {
        return null;
     }
 }

 System.out.println(construct(String.class).isEmpty()); // prints "true"

This uses Class<?>.newInstance() to construct an object using reflection, which doesn't always succeed (e.g. when there's no public nullary constructor).


Try something like:

public static <T> T createInstance(Class<T> clazz)
        throws IllegalArgumentException, SecurityException,
        InstantiationException, IllegalAccessException,
        InvocationTargetException, NoSuchMethodException {
    T ans = clazz.getConstructor().newInstance();
    return ans;
}


The correct choice is to use an Abstract Factory. Just pass it in, and it will even be able to create instances of classes that don't have public no-arg constructors, or of an appropriate implementation class of an interface class.

Reflection is absolutely unnecessary and the wrong choice here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜