The final
keyword identifies can be used to specify constant values . That (that is, final
indicates fields whose value values that cannot change during an invocation of a program execution).
However, constants that can change over the lifetime of a program should not be declared public final. The JLS allows implementations to insert the value of public final fields inline in any compilation unit that reads the field. Consequently, if the declaring class is edited such that the new version gives a different value for the field, compilation units that read the public final field may still see the old value until they are themselves re-compiled.
...
In this noncompliant code example, class Foo
declares a field whose value represents the version of the software. The field is subsequently accessed by class Bar
, which lives in from a separate compilation unit.
...
Code Block |
---|
You are using version 1 |
However, a subtle flaw is possible in the future. Suppose a developer updates the version number by modifying Foo.java, changing if a developer changes the value of VERSION
to be 2 . The developer then by modifying Foo.java
and recompiles Foo.java
, but fails to recompile Bar.java
. Now the software incorrectly prints:
Code Block |
---|
You are using version 1 |
because Bar.java still thinks that Foo.VERSION
is 1.
Although recompiling Bar.java
will solve solves this problem, a better solution is available.
...
Other than for true mathematical constants, we recommend that source code make very sparing use of class variables that are declared
static
andfinal
. If the read-only nature offinal
is required, a better choice is to declare aprivate static
variable and a suitable accessor method to get its value.
Thus Consequently, a compliant solution would beis:
Foo.java:
Code Block | ||
---|---|---|
| ||
class Foo { static private final int version = 1; static public final String getVersion() { return version; } // ... } |
...