Given this generic function:
<T> List<T> function() { return null; }
Why does this compile
List<String> l = function();
While this does not?
List<String> l = (List<String>) function();
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded.
Generics allows a type or method to operate on objects of various types while providing compile-time type safety, making Java a fully statically typed language. Generics are one of the most controversial Java language features.
Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time.
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.
Because when you do a cast like this:
(List<String>) function()
the compiler can't infer the type parameter for the function()
call, and falls back on binding T
to Object
.
While in
List<String> l = function();
it can infer the correct type for T
.
Note that you may cast if you circumvent the job of the type inference by explicitly providing the type:
import java.util.List;
class Test {
public static <T> List<T> function() { return null; }
public static void main(String[] args) {
List<String> l = (List<String>) Test.<String>function();
// ^^^^^^^^^^^^^
}
}
I don't know the exact type inferencing rules for generic parameters. They are however specified in JLS Section 15.12.2.7.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With