Java Reference
In-Depth Information
methods or constructors selected in the first phase. One method or constructor is
less specific
than
another if it can accept any parameters passed to the other [JLS 15.12.2.5].
In our program, both constructors are accessible and applicable. The constructor
Confusing(Object)
accepts any parameter passed to
Confusing(double[])
, so
Confusing(Object)
is less specific. (Every
double
array is an
Object
, but not every
Object
is a
double
array.) The most specific constructor is therefore
Confusing(double[])
, which explains the
program's output.
This behavior makes sense if you pass a value of type
double[]
; it is counterintuitive if you pass
null
. The key to understanding this puzzle is that
the test for which method or constructor is
most specific does not use the
actual parameters:
the parameters appearing in the invocation.
They are used only to determine which overloadings are applicable. Once the compiler determines
which overloadings are applicable and accessible, it selects the most specific overloading, using
only the
formal parameters
: the parameters appearing in the declaration.
To invoke the
Confusing(Object)
constructor with a
null
parameter, write
new
Confusing((Object)null)
. This ensures that only
Confusing(Object)
is applicable. More
generally,
to force the compiler to select a specific overloading, cast actual parameters to the
declared types of the formal parameters.
Selecting among overloadings in this fashion is unpleasant. In your APIs, ensure that clients aren't
forced to go to these extremes. Ideally, you should
avoid overloading:
Use different names for
different methods. Sometimes, this is not possible. Constructors don't have names, so they can't be
given different names. You can, however, alleviate the problem by making constructors private and
providing public static factories [EJ Item 1]. If constructors have many parameters, you can reduce
the need for overloading with the Builder pattern
[Gamma95]
.
If you do overload, ensure that all overloadings accept mutually incompatible parameter types, so
that no two are applicable at the same time. Failing that, ensure that all applicable overloadings
have the same behavior [EJ Item 26].
In summary, overload resolution can be confusing. Avoid overloading where possible. If you must
overload, obey the guidelines outlined here to minimize confusion. If a poorly designed API forces
you to select among overloadings, cast actual parameters to the types of the formal parameters of
the desired overloading.
< Day Day Up >
Search WWH ::
Custom Search