Java Reference
In-Depth Information
adopt((Point)p);
color = p.color;
}
If the programmer then runs the old binary file for
Test
with the new binary file for
ColoredPoint
, the output is still:
cp: (3,3,red)
because the old binary file for
Test
still has the descriptor “one parameter, whose type
is
Point
;
void
” associated with the method call
cp.adopt(cp2)
. If the source code for
Test
is
recompiled, the Java compiler will then discover that there are now two applicable
ad-
opt
methods, and that the signature for the more specific one is “one parameter, whose
type is
ColoredPoint
;
void
”; running the program will then produce the desired output:
cp: (3,3,green)
With forethought about such problems, the maintainer of the
points
package could fix
the
ColoredPoint
class to work with both newly compiled and old code, by adding de-
fensive code to the old
adopt
method for the sake of old code that still invokes it on
ColoredPoint
arguments:
public void adopt(Point p) {
if (p instanceof ColoredPoint)
color = ((ColoredPoint)p).color;
x = p.x; y = p.y;
}
Ideally, source code should be recompiled whenever code that it depends on is
changed. However, in an environment where different classes are maintained by dif-
ferent organizations, this is not always feasible. Defensive programming with careful
attention to the problems of class evolution can make upgraded code much more ro-
bust. See §13 for a detailed discussion of binary compatibility and type evolution.
15.12.2.1. Identify Potentially Applicable Methods
The class or interface determined by compile-time step 1 (§
15.12.1
) is searched for all
member methods that are potentially applicable to this method invocation; members inher-
ited from superclasses and superinterfaces are included in this search.
In addition, if the method invocation has, before the left parenthesis, a
MethodName
of the
form
Identifier
, then the search process also examines all member methods that are (a) im-