...
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 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.
...
Code Block | ||
---|---|---|
| ||
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 little idea about how they were generated or what they mean, and would, consequently, be unable to understand the function of this code.
...
This noncompliant code attempts to avoid the above issues by explicitly calculating the required constants.
Code Block | ||
---|---|---|
| ||
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.
...
Code Block | ||
---|---|---|
| ||
private static final intdouble 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.
...
The class java.lang.Math
defines a large set of numeric constants, such as including PI
and the exponential constant E
. Prefer the use of predefined constants when they are available.
Code Block | ||
---|---|---|
| ||
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
DCL02-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. The following noncompliant code example takes this rule too far.
Code Block | ||
---|---|---|
| ||
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 VOLUMNE_FACTOR * radius * radius * radius;
}
double greatCircleCircumference(double radius) {
return CIRCUMFERENCE_FACTOR * radius;
}
|
The . 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 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. Hence, replacing them with symbolic constants is inappropriateoverkill, and renders the code less readable.
Risk Assessment
Using numeric literals makes code more difficult to read, understand, and edit.
...