Java generics why can't I instantiate a genericized type [duplicate]
I was writing something using generics and to my surprise I found that this doesn't work:
class foo<T>{
T innerT = new T();
}
So can't I instantiate the genericized type? Aren't there any ways to do this?
At the runtime JVM doesn't know what T is so it can't create new object of type T. Types are erased during compilation.
Yeah, it's pretty damn annoying.
The work around I use is to force the client to pass the class in when constructing a new foo<T>
- i.e.
public foo(Class<T> myClass)
Then you can use myClass.newInstance()
instead.
I would always prefer a creational pattern (factory, prototype, ...). Especially
public foo(Class<T> myClass)
Then you can use
myClass.newInstance()
instead.
is a bad solution, because T may have no empty constructor.
The trick here is to "wrap" the constructor in its own object, and then use that object to create the class you need.
If you dont know what class you are instancing, well then you dont know if it has a constructor, thus you cant call it.
static <T> void myFunction(Provider<T> provider){
T t = provider.get();
}
interface Provider<T>{
public T get();
}
public class MyClass{
}
public static void main(String [] args){
myFunction(new Provider<MyClass>(){
public MyClass get(){
return new MyClass();
}
});
}
This is a limitation in the way java implemented generics. To allow compatibility of code using generics with legacy code before generics where added to the language, generics were implemented using type erasure. This causes a lot of confusion to people who come from langauges such as C++ and expect generic's to work in the same way.
To read more on the implications of this here is a good link
Workaround
You can use the template type of a class if you subtype it. See my answer to another question - Instantiating generics type in java.
精彩评论