Suppose you have legacy java code which can not be compiled by an up-to-date version of java. e.g.
public class ProviderUnavailableException extends Exception { private int cause; public int getCause(){ return cause; } // rest of implementation }
Back at the time of Java 1.3 this code was valid.
In Java 1.4 the class Throwable ‘redefined’ the method getCause(). It looks like this:
public Throwable getCause()
Now the legacy code is invalid (because ‘int’ is not a subtype of ‘Throwable’) but does not lead to runtime problems. Or can this happen under some circumstances?
Is it correct that back a the compile time, the compiler had generated the byte code to handle the execution of the method getCause solely in that class and therefore ‘knows’ that no super class has to be invoked?
EDIT
i checked the byte code of the legacy code with ‘javap -c’.
public int getCause(); Code: 0: aload_0 1: getfield #2; //Field _cause:I 4: ireturn
So it’s returning the local field. Seems ok for me.
In bytecode the method is referred to by its name, parameter types and return type. So the two methods are quite separate.
In the bytecode notation, your 1.3 method would be (I think):
While the new 1.4 method is:
You can see the signatures using
javap -s.Covariant return types are actually implemented at compile time by javac using synthetic bridge methods. They do not have runtime support. So if you override
Object run()withString run()javac will create both methods in the derived class withObject run()callingString run().