Java Reference
In-Depth Information
private Words() { }; // Uninstantiable
public static final String FIRST =
"physics";
public static final String SECOND =
"chemistry";
public static final String THIRD =
"biology";
}
What does the client program print?
Solution 93: Class Warfare
A quick look suggests that the program should print
physics chemistry biology
; after all, Java
loads classes at run time, so it always has access to the latest version of a class. A deeper analysis
suggests otherwise.
References to constant fields are resolved at compile time to the constant
values they denote
[JLS 13.1]. Such fields are technically, if oxymoronically, known as
constant
variables
. A constant variable is defined as a variable of primitive type or type
String
that is final
and initialized with a compile-time constant expression [JLS 4.12.4]. With the benefit of this
knowledge, it would be reasonable to think that the client program compiles the initial values of
Words.FIRST
,
Words.SECOND
, and
Words.THIRD
into its class file and prints
the null set
,
regardless of whether the class
Words
has been modified.
Reasonable, perhaps, but not correct. If you ran the program, you found that it prints
the
chemistry set
. This seems truly bizarre. Why would it do a thing like that? The answer is to be
found in the precise definition of the term
compile-time constant expression
[JLS 15.28]. The
definition is too long to reproduce here, but the key to understanding the behavior of the program is
that
null is not a compile-time constant expression.
Because constant fields are compiled into clients,
API designers should think long and hard
before exporting a constant field.
If a field represents a true constant, such as p or the number of
days in a week, there is no harm in making it a constant field. If, however, you want clients to adapt
to changes in the field, make sure that it isn't a constant. There is an easy way to do this: If you
initialize a field, even a final field, with an expression that isn't constant, the field isn't constant.
You can turn a constant expression into a nonconstant by passing it to a method that simply returns
its input parameter.
If we modify the class
Words
to use such a method,
PrintWords
will print
physics chemistry
biology
after
Words
is again modified and recompiled:
Search WWH ::
Custom Search