public class Null { public static void greet() { System.out.println("Hello world!"); } public static void main(String[] args) { ((Null) null).greet(); } }
Solution 54: Null and Void
This program looks as though it ought to throw a
NullPointerException. The main method invokes the
greet method on the constant null, and you can't invoke a
method on null, can you? Well, sometimes you can. If you ran the
program, you found that it prints "Hello world!"
The key to understanding this puzzle is that
Null.greet is a static method. As you saw in Puzzle 48, it is a bad idea to use an
expression as the qualifier in a static method invocation, but that is exactly
what this program does. Not only does the run-time type of the object referenced
by the expression's value play no role in determining which method gets invoked,
but also the identity of the object, if any, plays no role. In this case, there
is no object, but that makes no difference. A
qualifying expression for a static method invocation is evaluated, but its value
is ignored. There is no requirement that the value be non-null.
To eliminate the confusion in this program, you could invoke
the greet method by using its class as a qualifier:
public static void main(String[] args) { Null.greet(); }
Better yet, you could eliminate the qualifier entirely:
public static void main(String[] args) { greet(); }
In summary, the lesson of this puzzle is exactly the same as
that of Puzzle 48:
Qualify static method invocations with a type, or don't qualify them at all. For
language designers, it should not be possible to pollute the invocation of a
static method with an expression, which serves only to confuse.
No comments:
Post a Comment
Your comments are welcome!