I have a really hard time understanding the finer points of generics. When I create a type that looks like this:
I would be able to do almost everithing inside that class with my type parameter E, except create new instances of anything, right?
I couldnt just go and do something like this:
Is there some way I could do something like that? Because this would be tremendously helpful. If not, why is this not allowed? (Aside from compiler complexity)
The reason I ask is, that if it was possible, my abstract superclass could take care of the instantiation and the subclasses wouldn't have to implement the methods that use paramterized instantiations. This would save me a lot of redundant code.
I thought of using reflection to find out what type E is as a workaround. But I can't find any methods that would support that.
regards, Fred [ December 02, 2007: Message edited by: Fred Woosch ]
Joined: Jan 30, 2000
Two reasons. The main one is that, in order to be backward-compatible with pre-existing Java code, generics for the most part do not exist in in the JVM, only the compiler. If you create a
then the compiler will remember that for ConcreteConfigurableEntity, parameter E means Foo. But the JVM does not know that, and thus would have no way of knowing that Foo is the class it should create.
The second reason is that a parameter like E doesn't necessarily get bound to a single specific class. Depending on how it's used, E may be a single class, an interface or abstract class, or a ranget of types, like ? extends Number, or ? extends Collection super SortedSet. In cases like these, how could new E() be interpreted? It can't, really.
If you want to be able to create a new E, one way is to use a Class instance to lock E down to a specific class. E.g.
This forces users to specify a specific class when they create the GenericClass. They still need to choose a concrete class with a public non-arg constructor. But at least this is a possible approach that will work for many applications, if not all.
When compiling, the compiler performs something called type erasure. Basically, this means that any generic type gets replaced by Object.
Now there is another reason you can't do something like "new E()". What if E does not have a non-args constructor? The compiler knows very little about E. Worst case, it only knows it's some subclass of Object.
Consider the following code:
Sure, the first object (Object) can be created. But what about the Integer? The String?
Generics add too many uncertainties to allow creating objects just like that. You'll have to use workarounds like using a Class object like Jim suggested.