The static type of z is A , so zf(-6) can only bind to a method in A , which in this case is Af(int) .
The language is designed so that
A z = new B(3.0); zf(-6);
will always behave the same way
A z = complicatedWayToComputeTrue() ? new B(3.0) : new A(3.0); zf(-6);
If the compiler had to bind to a different method signature because it can prove that A z always contains B , then this will lead to all kinds of non-local effects for the language, which makes it very difficult to debug or support java.
Imagine someone trying to support
final A z = complicatedWayToComputeTrue() ? new B(3.0) : new A(3.0);
changing it to
A z = new B(3.0);
If the compiler can now prove that A always B and binds Zf to the method in B , the maintainer will be puzzled.
source share