What happens in java jvm executing legacy code that was canceled by a language change

Suppose you have legacy Java code that cannot be compiled with an updated version of java. eg.

public class ProviderUnavailableException extends Exception { private int cause; public int getCause(){ return cause; } // rest of implementation } 

Back during Java 1.3, this code was valid.

In Java 1.4, the Throwable class overrides the getCause () method. It looks like this:

 public Throwable getCause() 

Now legacy code is invalid (since "int" is not a subtype of "Throwable"), but does not lead to run-time problems. Or can this happen in some circumstances?

Is it correct that the compilation time was back, the compiler generated byte code to handle the execution of the getCause method only in this class and, therefore, “knows” that the super-class should not be called?

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 returns a local field. Seems good to me.

+4
source share
2 answers

In bytecode, a method refers to its name, parameter types, and return type. So the two methods are pretty separate.

In bytecode notation, your method 1.3 will (I think):

 getCause()J 

While the new method 1.4:

 getCause()Ljava/lang/Throwable; 

You can see the signatures with javap -s .

Covariant return types are actually implemented during javac compilation using synthetic bridge methods. They do not have runtime support. Therefore, if you override Object run() using String run() , javac will create both methods in the derived class using Object run() , which calls String run() .

+5
source

Firstly, a signature change is not a language change. Updating libraries is not a syntactic or functional change for the java language. Your question is about how later binding methods bind methods. The easiest way to check is to simulate the same problem as your classes, replacing your own.

+1
source

All Articles