Why is a ClassCastException only thrown when the return value is accessed?
-
13-09-2019 - |
Question
Related to this question
Given this function:
public static <S extends CharSequence> S foo(S s) {
return (S) new StringBuilder(s);
}
Why does this invocation execute without exception:
foo("hello");
But this one throws ClassCastException?
System.out.println(foo("hello"));
Solution
Generics in Java 5/6 are type-erased, which means that any generic type is fundamentally just an Object
type (or whatever the least common denominator type is, which is in this case CharSequence
) at runtime. The appropriate casts are inserted wherever needed. So your method gets type-erased to something that looks like this:
public static CharSequence foo(CharSequence s) {
return (CharSequence) new StringBuilder(s);
}
And your call gets type-erased to this:
System.out.println((String)foo("hello"));
Apparently Java won't bother inserting the (String)
cast if the return value is never used—why bother?
OTHER TIPS
Generic types are only available to the compiler, and are erasured (basically omitted) at runtime. So the cast is ignored within the method