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