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 in a program can lead to two problems: first. First, the meaning of the literal is often obscured or unclear from the context (from which they derive the name "magic numbers"), and second. Second, changing a frequently - used literal requires searching the entire program source code to be searched for occurances of that literal , creating possible error sources if some of the occurances of the literal are overlooked.and distinguishing the uses that must be modified from those that should remain unmodified.

Avoid these problems by declaring class variables with meaningfully named constants, setting their values A solution to this problem is to declare meaningfully-named constants at the start of the program whose values are set equal to the desired literals, and to refrence these constants rather than referencing the constants instead of the literals themselves throughout the program. The advantages to this approach are that the constant's name can indicate This approach clearly indicates the meaning or intended use of each literal. Furthermore, should the constant require modification, and should the constant need to be changed, this can be accomplished simply by editing the constant declaration without having to search the code for all uses of it.

final

The final keyword in Java is used to declare constants. Its effect is to render the affected variable immutable. Attempting to change the value of a final-qualified variable results in a compile-time error.

The following code fragment demonstrates its use:

the change is limited to the declaration; searching the code is unnecessary.

Constants should be declared as static and final. However, constants should not be declared public and final if their values might change (see DCL59-J. Do not apply public final to constants whose value might change in later releases for more details). For example,

Code Block
private static 
Code Block

final int SIZE = 25;

This code declares the value SIZE to be of type int and to have the immutable value 25. This constant can subsequently be used whenever the value 25 would be neededAlthough final can be used to specify immutable constants, there is a caveat when dealing with composite objects. See OBJ50-J. Never confuse the immutability of a reference with that of the referenced object for more details.

Noncompliant Code Example

The following This noncompliant code example calculates various approximate dimensions of a sphere, given its radius.:

Code Block
bgColor#ffcccc

double area(double radius) {
  return 123.5614 * 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 arbitrary literals 123.5614, 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 no little idea about how they were generated or what they meant, mean and consequently would therefore be unable to not understand the function of this code.

Noncompliant Code Example

The following This noncompliant code example attempts to avoid the above issues problem 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 it 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 was needed, he would need to find all occurances of "π is desired, all occurrences of 3.14" in the code and replace themwould have to be found and replaced.

Compliant Solution (Constants)

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

Code Block
bgColor#ccccff

private static final intdouble PI = 3.14;

double area(double radius) {
  return 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 technique reduces clutter and promotes maintainability. If a more precise approximation of the value of π is required, the programmer can simply redefine the constant. The use of the literals 4.0, 3.0, and 2 does not violate this guideline, for reasons explained in the "Applicability" section of this guideline.

Compliant Solution (Predefined Constants)

Use predefined constants when they are available. The class java.lang.Math defines a large group of numeric constants, including PI and the exponential constant E.

Code Block
bgColor#ccccff
double area(double radius) {
  return 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;
}

Noncompliant Code Example

This noncompliant code example defines a constant BUFSIZE but then defeats the purpose of defining BUFSIZE as a constant by assuming a specific value for BUFSIZE in the following expression:

Code Block
bgColor#FFcccc
private static final int BUFSIZE = 512;

// ...

public void shiftBlock() {
  int nblocks = 1 + ((nbytes - 1) >> 9);  // BUFSIZE = 512 = 2^9
  // ...
}

The programmer has assumed that BUFSIZE is 512, and right-shifting 9 bits is the same (for positive numbers) as dividing by 512. However, if BUFSIZE changes to 1024 in the future, modifications will be difficult and error prone.

This code also fails to conform to NUM01-J. Do not perform bitwise and arithmetic operations on the same data. Replacing a division operation with a right shift is considered a premature optimization. Normally, the compiler will do a better job of determining when this optimization should be performed.

Compliant Solution

This compliant solution uses the identifier assigned to the constant value in the expression:

Code Block
bgColor#ccccff
private static final int BUFSIZE = 512;

// ...

public void shiftBlock(int nbytes) {
  int nblocks = 1 + (nbytes - 1) / BUFSIZE;
  // ...
}

Applicability

Using numeric literals makes code more difficult to read, understand, and edit.

The use of symbolic constants should be restricted to cases in which they improve the readability and maintainability of the code. When the intent of the literal is obvious, or where the literal is not likely to change, using symbolic constants can impair code readability. The following code example obscures the meaning of the code by using too many symbolic constants.

Code Block
bgColor#ffcccc
private static final double FOUR = 4.0;
private static final double THREE = 3.0;

double volume(double radius) {
  return FOUR / THREE * Math.PI * radius * radius * 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 π), so they can be represented exactly. There is no reason to change them to increase precision because replacing them with symbolic constants actually impairs the readability of the code.

Bibliography

 

...

Image Added Image Added Image AddedThis both clarifies the code and allows easy editing, for if a different value for pi is required, the programmer can simply redefine the constant.