Versions Compared

Key

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

Java supports the use of various types of literals, such as integers (5, 2), floating point numbers (2.5, 6.022e+23), characters ('a', '\n'), booleans Booleans ('true', 'false'), and strings ("Hello\n"). Extensive use of literals within a program can lead to two problems: first, the meaning of the literal is often obscured or unclear from the context (magic numbers); second, changing a frequently-used literal requires both searching the entire program source for occurrences of that literal, and also distinguishing the uses that must be modified from those that should remain unmodified.

Avoid these problems by declaring meaningfully-named constants as class variables, setting their values to the desired literals, and referencing the constants in place of the literals throughout the program. This approach allows the use of a name naming that clearly indicates the meaning or intended use of the literal. Further, should the constant require modification, the change is limited to the declaration; searching the code is unnecessary.

final

The final keyword in Java is used to declare constants. Its effect is to render the affected non-composite variable immutable. Attempts to change the value of a final-qualified variable after it has been initialized result in a compile-time error. Because 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. (See guideline DCL04-J. Do not apply public final to constants whose value might change in the future.)

The following code fragment demonstrates the use of static and final to create a constantConstants should be declared as static and final, for example:

Code Block
private static final int SIZE = 25;

This code snippet declares the value SIZE to be type int and value 25. 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 Although final can be used to specify immutable constants, there is a caveat when dealing with composite objects (mutable data in particular). See guideline OBJ01-J. Do not assume that declaring a reference to be final causes the referenced object to be immutable 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 A developer or maintainer reading this code would have little idea about how they were generated or what they mean, and consequently would , consequently, be unable to understand the function of this code.

Noncompliant Code Example

This noncompliant code example 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, all occurrences of 3.14 in the code would have to be found and replaced.

Compliant Solution (Constants)

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 double 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. If a more precise value of pi ? is required, the programmer can simply redefine the constant.

...

Code Block
bgColor#ffcccc
private static final double AREA_FACTOR = 4.0 * Math.PI;
private static final double VOLUME_FACTOR = 4.0 / 3.0 * Math.PI;
private static final double CIRCUMFERENCE_FACTOR = 2.0 * Math.PI;

double area(double radius) {
  return AREA_FACTOR * radius * radius;
}

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

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

The values 4.0 and 3.0 in the volume calculation are clearly scaling factors used to calculate the sphere's volume and are not subject to change (unlike the approximate value for pi?), so they can be represented exactly; there is no reason to change them to increase precision. HenceTherefore, replacing them with symbolic constants impairs the readability of the code.

...