Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The final keyword in Java is used to declare constants. Its effect is to render the affected non-composite variable immutable. Attempting to change the value of a final-qualified variable results in a compile-time error. As constants cannot be changed, it is desirable to define only one instance of them for the class; consequently constants should also be declared with the static modifier as well. (DCL31-J. Qualify mathematical constants with the static and final modifiers)

...

Code Block
private static final int SIZE = 25;

This code snippet declares the value SIZE to be of the type int and assigns 25 to it. This constant can subsequently be used wherever the value 25 is needed.

Although final is most often safe for creating compile time immutable constants, its use has a few caveats when dealing with composite objects (mutable data in particular). See OBJ03-J. Be careful about final reference for more details.

...

Code Block
bgColor#ffcccc
double area(double radius) {
return 12.56 * radius*radius; }

double volume(double radius) {
return 4.19 * radius * radius * radius; }

double greatCircleCircumference(double radius) {
return 6.28 * radius; }

The methods use the seemingly-random literals 12.56, 4.19, and 6.28 to represent various scaling factors used to calculate these dimensions. Someone reading this code would have no little idea about how they were generated or what they meantmean, and would consequently be unable to understand the function of this code.

Noncompliant Code Example

The following This noncompliant code attempts to avoid the above issues by explicitly calculating the required constants

Code Block
bgColor#ffcccc
double area(double radius) {
return 4.0 * 3.14 * radius * radius; }

double volume(double radius) {
return 4.0/3.0 * 3.14 * radius * radius * radius; }

double greatCircleCircumference(double radius) {
return 2 * 3.14 * radius; }

The code uses the literal 3.14 to represent the value pi. Although this removes some of the ambiguity from the literals, it complicates code maintenance. If the programmer were to decide that a more precise value of pi is desired, he would need to find all occurrences of 3.14 in the code and replace themwould have to be found and replaced.

Compliant Solution

In this compliant solution, a constant PI is first declared and initialized to 3.14. Thereafter, it is referenced in the code whenever the value of pi is needed.

Code Block
bgColor#ccccff
private static final int PI = 3.14;

double area(double radius) {
return 4.0 * PI * radius * radius; }

double volume(double radius) {
return 4.0/3.0 * PI * radius * radius * radius; }

double greatCircleCircumference(double radius) {
return 2 * PI * radius; }

This reduces clutter and promotes maintainability, for if a different value for of pi is required, the programmer can simply redefine the constant.

...

Code Block
bgColor#ccccff
double area(double radius) {
return 4.0 * Math.PI * radius * radius; }

double volume(double radius) {
return 4.0/3.0 * Math.PI * radius * radius * radius; }

double greatCircleCircumference(double radius) {
return 2 * Math.PI * radius; }

Exceptions

EX1: The use of symbolic constants should be restricted to cases where they improve the readability and maintainability of the code. Using them when the intent of the literal is obvious, or where the literal is not likely to change, can impair code readability. In the preceding compliant solution, the values 4.0 and 3.0 in the volume calculation are clearly scaling factors used to calculate the circle volume, and as such are not subject to change (unlike pi, they can be represented exactly; there is no reason to change them to increase precision). Hence, replacing them with symbolic constants would be is inappropriate.

Risk Assessment

...