I found a lot of posts about how to overcome this limitation, but none about why this limitation exists (except this one, which just mentions it has to do with type era
Short answer:
Java is a compiled programming language, which means that your bytecode is constant at runtime. It is impossible to generate bytecode for new E()
if E
is unknown.
Explanation: Generic information is erased in runtime:
public class Container {
private E item;
public E getItem() {return item;}
}
class BoxWithPresent extends Container {
}
class SimpleBox extends Container {
}
In bytecode class BoxWithPresent
contains field item
of type Present
, but class SimpleBox
contains field item
of type Object
(because type E
was not specified).
Now you write abstract instantiation method:
public class Container {
public E createE() {
return new E(); // imagine if that was allowed
}
}
What bytecode should be generated here? .class
file is generated right now, at compilation time, but we have no idea what is E
type.
So.. can new T()
be replaced with new Object()
? Bad idea, class BoxWithPresent
won't like it, because it expects that E
is Present
.
Can it be replaced with class.newInstance()
? Again no, there is no class
variable in method scope.
That's why new E()
is impossible.
But there are workarounds with passing class
as parameter, or extracting generic information.