views:

64

answers:

3

I need to do some refactoring in Java, and I need to maintain some degree of binary compatibility. In this case I want to remove some legacy interfaces, that are not used anywhere anymore and which require a rather big (and also deprecated) external dependency.

I have class C that implements interface I, and I have code that calls a method (declared in the interface) on an instance of C. The calling code knows that it is using C, not just the interface.

 class C implements I {
      void theMethod(){} ; // is declared in the interface I
 }

 C object;
 object.theMethod();

When I remove the interface from the class definition (but keep all the methods), will the calling code (which does not refer to the interface at all) still work (without a recompile)?

+5  A: 

Yes, it will work - as long as it doesn't explicitly refer to interface I anywhere.

From JLS: Resolution of Symbolic References:

The binary representation of a class or interface references other classes and interfaces and their fields, methods, and constructors symbolically, using the binary names (§13.1) of the other classes and interfaces

Class ClientClass referring to field / method of class C contains no implicit references to interface I that class may implement.

ChssPly76
Does this mean that I can even remove abstract base classes and put the methods in the now parent-less child class?
Thilo
Yes, same rules apply. Base class doesn't even have to be abstract - as long as you "flatten" the entire hierarchy to child class **AND** base class(es) were never explicitly referenced from client code you'll be fine.
ChssPly76
Here's a JLS section on method / constructor declarations: http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#45197
ChssPly76
+1  A: 

You might have a problem with the calling Code if it imports the Interface anywhere. If there is no import of the interface in any of the calling code, you can be reasonably confident that your refactoring will work as planned.

Steve De Caux
Yes, the only place where the interface in question is used is (or should be by now...) the class declaration.
Thilo
+2  A: 

It works as long as an object of class C is never referred to as I.

You can also refer to Evolving Java-based APIs part 2.

Gregory Pakosz