I am trying to understand the Java dispatch system. Here is the code I am trying to think through,
When I run new B(0), it is understandable why it prints 10 and 10 - because in both cases I am printing referring to the instance variable in class A.
But in new B(), the second line in test() function does not seem to refer to the instance method of A, and instead, it seems to refer to the instance method of B despite the cast to A.
Why the cast is working with instance variable but not for instance methods?
Because non-private instance methods are 'virtual' and fields are not. That means that a call to a non-private instance method will always call the version provided by the actual runtime type of the object (which is B), unless you use a special keyword like super.
Fields, static methods and private methods are not virtual. If you redeclare a field, static method or private method in a subclass, a whole new field/method is created that happens to have the same name as the one in the superclass. With instance methods, when you redeclare a method with the same name, it will also refer to the actual same method as the one in the superclass.
That means that a call to a non-private instance method will always call the version provided by the actual runtime type of the object
But isn't the runtime type changed to A by the cast in line 34?
Stephan van Hulst
posted 2 weeks ago
No. Only primitives change their runtime type when you cast them. The only thing that casting an object reference does at runtime is check that the actual type really is the type that you cast the reference to or throw an exception. No conversion takes place at all.
Explicitly casting an object reference to a supertype is pointless:
It won't affect how non-private instance methods are dispatched.
Static methods should be called on a class name and not on an object reference.
Fields should not be accessed by other classes at all.