Java Reference
In-Depth Information
Solution 71: Import Duty
You might expect the program to print
[1, 2, 3, 4, 5]
, and indeed it would, if only it compiled.
Sadly, the compiler just can't seem to find the right
toString
method:
ImportDuty.java:9:Object.toString can't be applied to (Object[])
System.out.println(toString(args));
^
Is the compiler just being dense? Why would it try to apply
Object.toString()
, which doesn't
match the call's parameter list, when
Arrays.toString(Object[])
matches perfectly?
The first thing the compiler does when selecting a method to be invoked at run time is to choose the
scope in which the method must be found [JLS 15.12.1]. The compiler chooses the smallest
enclosing scope that has a method with the right name. In our program, this scope is the class
ImportDuty
, which contains the
toString
method inherited from
Object
. This scope has no
applicable method for the invocation
toString(args)
, so the compiler must reject the program.
In other words, the desired
toString
method isn't in scope at the point of the invocation. The
imported
toString
method is
shadowed
by a method with the same name inherited into
ImportDuty
from
Object
[JLS 6.3.1]. Shadowing is a lot like obscuring (
Puzzle 68
). The key
distinction is that a declaration can shadow another declaration only of the same kind: One type
declaration can shadow another, one variable declaration can shadow another, and one method
declaration can shadow another. By contrast, variable declarations can obscure type and package
declarations, and type declarations can obscure package declarations.
When one declaration shadows another, the simple name refers to the entity in the shadowing
declaration. In this case,
toString
refers to the
toString
method from
Object
. Simply put,
members that are naturally in scope take precedence over static imports.
One consequence is
that static methods with the same name as
Object
methods cannot be used with the static import
facility.
Since you can't use static import with
Arrays.toString
, use a normal import declaration instead.
This is the way
Arrays.toString
was meant to be used:
import java.util.Arrays;
class ImportDuty {
static void printArgs(Object... args) {
System.out.println(
Arrays.
toString(args));
Search WWH ::
Custom Search