tags:

views:

104

answers:

2

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.

+5  A: 

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):

getCause()J

While the new 1.4 method is:

getCause()Ljava/lang/Throwable;

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() with String run() javac will create both methods in the derived class with Object run() calling String run().

Tom Hawtin - tackline
+1  A: 

Firstly the signature change is not a language change. Updating libraries is not a syntactical or feature change for java the language. Your question relates to how the runtime late binds methods. The easiest way to verify is to simulate the same problem USO g your classes substituting your own.

mP