I have seen this question, but it does not seem to answer both cases below and does not reference any further documentation, which I'd love to read.
I have the following fragment of code:
public static void main(String[] args) {
// compile-time OK
// run-time ClassCastException
Child noWarnings = (Child) getParent();
// vs...
// compile-time failure
Child compileTimeFailure = new Parent();
}
private static Parent getParent() {
return new Parent();
}
private static class Parent { }
private static class Child extends Parent { }
The code on line 4 of the snippet produces no warnings, but results in a ClassCastException
. Why is the compiler unable to typecheck this?
This gets even weirder if we add a layer of indirection:
public static void main(String[] args) {
// compile-time OK
// run-time ClassCastException
Boxed noWarnings = new Boxed((Child) getParent());
// vs...
// compile-time OK, but warning is emitted correctly
// run-time ClassCastException
Boxed classCastWarning = new Boxed((Child) new Parent());
}
private static Parent getParent() {
return new Parent();
}
private static class Boxed {
public Boxed(Child data) {
}
}
private static class Parent { }
private static class Child extends Parent { }
It seems un-intuitive that the compiler does not allow the first example, but allows the second.
Any light shed on either of these case would be most welcome.