If an instance method is added to a subclass and it overrides a method in a superclass, then the subclass method will be found by method invocations in pre-existing binaries, and these binaries are not impacted. If a class method is added to a class, then this method will not be found, because the invocation of a class method is resolved at compile time to use the fully qualified name of the class where the method is declared. Thus if the example:
class Hyper { void hello() { System.out.print("Hello, "); } static void world() { System.out.println("world!"); } } class Super extends Hyper { } class Test { public static void main(String[] args) { Super s = new Super(); s.hello(); s.world(); } }
is compiled and executed, it produces the output:
Hello, world!
Suppose that a new version of class Super
is produced:
class Super extends Hyper { void hello() { System.out.print("Goodbye, cruel "); } static void world() { System.out.println("earth!"); } }
If Super
is recompiled but not Hyper
or Test
, then running the new binary with
the existing binaries for Hyper
and Test
will produce the output:
Goodbye, cruel world!
This example demonstrates that the invocation in:
s.world();
in the method main
is resolved, at compile time, to a symbolic reference to the
class containing the class method world
, as though it had been written:
Hyper.world();
This is why the world
method of Hyper
rather than Super
is invoked in this
example. Of course, recompiling all the classes to produce new binaries will allow
the output:
Goodbye, cruel earth!