Java Reference
In-Depth Information
If you tried the program, you found that it won't even compile. The compiler error is less than
helpful:
Pet.java:28: cannot find symbol
symbol: method sleep()
sleep();
^
Why can't the compiler find the symbol? It's right there in black and white. As in
Puzzle 74
, the
problem stems from the details of the overload resolution process. The compiler searches for the
method in the innermost enclosing scope containing a method with the correct name [JLS 15.12.1].
For the
sleep
invocation in our program, that scope is the anonymous class containing the
invocation, which inherits the methods
Thread.sleep(long)
and
THRead.sleep(long,int)
. These
are the only methods named
sleep
in that scope, and neither is applicable to this invocation
because both require parameters. As neither candidate for the invocation is applicable, the compiler
prints an error message.
The
sleep
methods inherited into the anonymous class from
Thread
shadow
[JLS 6.3.1] the desired
sleep
method. As you saw in
Puzzles 71
and
73
, you should
avoid shadowing.
The shadowing in
this puzzle is indirect and unintentional, which makes it even more insidious than usual.
The obvious way to fix the program is to change the name of the
sleep
method in
Pet
to
snooze
,
doze
, or
nap
. Another way to fix the problem is to name the class explicitly in the method
invocation, using the
qualified
this
construct [JLS 15.8.4]. The resulting invocation is
Pet.this.sleep()
.
The third and arguably best way to fix the problem is to take the advice of
Puzzle 77
and
use the
THRead(Runnable)
constructor instead of extending
Thread
.
If you do this, the problem goes
away because the anonymous class does not inherit
THRead.sleep
. This simple modification to the
program produces the expected, if tiresome, output:
public void live() {
new Thread(
new Runnable()
{
public void run() {
while (true) {
eat();
play();
Search WWH ::
Custom Search