Java Reference
In-Depth Information
Solution 63: More of the Same
This program looks straightforward. The
main
method creates a
MoreNames
instance by invoking the
parameterless constructor. The
MoreNames
instance contains a private
Map
field (
m
), which is
initialized to an empty
HashMap
. The parameterless constructor appears to put two mappings into
the map
m
, both with the same key (
Mickey
). As we know from the previous puzzle, the ballplayer
(Mickey Mantle) should overwrite the rodent (Mickey Mouse), leaving a single mapping. The
main
method then invokes the
size
method on the
MoreNames
instance, which in turn invokes
size
on
the map
m
and returns the result, presumably
1
. There's only one problem with this analysis: The
program prints
0
, not
1
. What's wrong with the analysis?
The problem is that
MoreNames
has no programmer-declared constructor. What it does have is a
void
-returning instance method called
MoreNames
, which the author probably intended as a
constructor. Unfortunately, the presence of a return type (
void
) turned the intended constructor
declaration into a method declaration, and the method never gets invoked. Because the
MoreNames
has no programmer-declared constructor, the compiler helpfully (?) generates a public
parameterless constructor that does nothing beyond initializing the field of the instance that it
creates. As previously mentioned,
m
is initialized to an empty
HashMap
. When the
size
method is
invoked on this
HashMap
, it returns
0
, and that is what the program prints.
Fixing the program is as simple as removing the
void
return type from the
Names
declaration, which
turns it from an instance method declaration into a constructor declaration. With this change, the
program prints
1
as expected.
The lesson of this puzzle is:
Don't accidentally turn a constructor declaration into a method
declaration by adding a return type.
Although it is legal for a method to have the same name as
the class in which it's declared, you should never do this. More generally,
obey the standard
naming conventions
, which dictate that method names begin with lowercase letters, whereas class
names begin with uppercase letters.
For language designers, perhaps it was not such a good idea to generate a default constructor
automatically if no programmer-declared constructor is provided. If such constructors are
generated, perhaps they should be private. There are several other approaches to eliminating this
trap. One is to prohibit method names that are the same as their class name, as does C#. Another is
to dispense with constructors altogether, as does Smalltalk.
< Day Day Up >
Search WWH ::
Custom Search