This question was inducted by this StackOverflow question about unsafe casts: Java Casting method without knowing what to cast to. While answering the question I encount
If you can't find it in the specification, that means it's not specified, and it is up to the compiler implementation to decide where to insert casts or not, as long as the erased code meets the type safety rules of non-generic code.
In this case, the compiler's erased code looks like this:
public static Object identity(Object x) {
return x;
}
public static void main(String args[]) {
String a = (String)identity("foo");
System.out.println(a.getClass().getName());
Object b = identity("foo");
System.out.println(b.getClass().getName());
}
In the first case, the cast is necessary in the erased code, because if you removed it, the erased code wouldn't compile. This is because Java guarantees that what is held at runtime in a reference variable of reifiable type must be instanceOf
that reifiable type, so a runtime check is necessary here.
In the second case, the erased code compiles without a cast. Yes, it will also compile if you added a cast. So the compiler can decide either way. In this case, the compiler decided not to insert a cast. That is a perfectly valid choice. You should not rely on the compiler to decide either way.