Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactored methods and binary compatibility in Java

When refactoring methods it is easy to introduce binary incompabilities (with previous versions of the code) in Java.

Consider changing a method to widen the type of its parameter to a parent interface:

 void doSomething(String x);

 // change it to

 void doSomething(CharSequence c);

All the code that uses this method will continue to compile without changes, but it does require a re-compile (because the old binaries will fail with a MethodNotFoundError).

How about pulling a method up into a parent class. Will this require a re-compile?

// before
public class B extends A{
    protected void x(){};
}

// after
public class A {
    public void x(){};
}
public class B extends A{}

The method has been moved from B to the parent A. It has also changed visibility from protected to public (but that is not a problem).

Do I need to maintain a "binary compatibility wrapper" in B, or will it continue to work (automatically dispatch to the parent class)?

 // do I need this ?
 public class B extends A{
     // binary compatibility wrapper
     public void x(){ super.x(); }
 }
like image 601
Thilo Avatar asked Sep 02 '09 01:09

Thilo


1 Answers

"Widening" affects the signature of the method so that is not binary compatible. Moving a method to a superclass does not affect the method signature, so it will work. Eclipse has a great document that describes API and ABI compatibility:

http://wiki.eclipse.org/Evolving_Java-based_APIs

More explicit rules are in part 2:

http://wiki.eclipse.org/Evolving_Java-based_APIs_2

I believe you're interested in "Change type of a formal parameter" (i.e., what you refer to as widening) or "Move API method up type hierarchy" (i.e., what you refer to as pull into a parent class).

like image 164
Brett Kail Avatar answered Oct 06 '22 00:10

Brett Kail