Java why is conversion from "lower" class to a "higher" class not forbidden?

Let A and B be and classes and let B extend A. Consider

B b=(B)new A();

This will obviously give an error because A does contain less Variables and Methods than B. But why doesnt Java forbid it. Because for example every method in an interface must be implemented all the time, because if it were different, it would give an error while instatiating or a final abstract class is not possible because it must be extended.


Solution 1:

Let's look at your line of code:

B b=(B)new A();

with

class B extends A { ... }

The Java compiler's intelligence is limited. Not everything that's obvious to us humans is detected by the compiler.

Our human reasoning goes like this:

  • new A() gives an object of class A, and exactly of class A, not a subclass.
  • With (B)new A() we want to treat it as an instance of B or one of its subclasses.
  • As we know that it is an instance exactly of class A, we conclude that casting to B is wrong.

The key to our reasoning is the phrase "exactly of class A", excluding any A subclass.

The compiler simply doesn't reason like that, it never excludes subclasses. Its reasoning is:

  • new A() gives an object of class A, so the expression type is A, implicitly including all A subclasses.
  • The expression (B)new A() wants to treat it as an instance of B or one of its subclasses. To the compiler, that's perfectly possible, as B is a subclass of A, so an expression of type A can indeed be of type B.
  • So, the compiler allows that line of code although it will surely throw a ClassCastException at runtime.

The key is that the compiler only reasons along a concept of expression type that always implicitly includes subclasses, and does not have a special treatment for expressions where subclasses are impossible.