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(); }
}
"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).
It should continue to work automatically as Java has dynamic linking
来源:https://stackoverflow.com/questions/1365409/refactored-methods-and-binary-compatibility-in-java