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.
精彩评论