Static Members and Class Variables
A named constant gives a meaningful name to a value that is meant to stay fixed for the whole program.
A Number Without a Name
Many programs contain a quantity that is meant to stay the same for the whole run. Consider an interest rate of 0.05 that a program uses to compute growth. The number 0.05 is just a bare value with no description attached. Anyone reading a line that contains 0.05 has to work out, from context, what that number stands for. A named constant is the Java tool for attaching a meaningful name to a value like this.
Compare two versions of the same update line. The first reads principal += principal*interestRate, and it tells the reader what is happening. The second reads principal += principal*0.05, and it forces the reader to guess what 0.05 represents. Both lines compute the same result, but only the first one explains itself. Before reading on, decide which version you would rather find in a program you had to maintain.
Tracing the Interest Rate Update
Read the following class and trace what happens when addInterest is called. Notice how the name INTEREST_RATE carries the meaning that the literal 0.05 lacks. The program's behavior is the same either way, but the reader's experience is not.
- INTEREST_RATE is declared once, at class level, with a fixed value of 0.05
addInterestreads the constant by name, so its meaning is visible at the point of use- principal is an ordinary variable because the program changes it as it runs
What do you think happens?
If an Account starts with a principal of 100.0 and addInterest is called once, what is the principal afterward?
Reveal answer
105.0
The update computes principal + principal * 0.05, which is 100.0 + 5.0 = 105.0. The constant does not change the arithmetic; it only names the rate.
Declaring a Named Constant
In Java, the modifier final can be placed on a variable declaration. Its effect is to guarantee that the value stored in the variable cannot be changed after the variable has been initialized. Applied to the interest rate, a member variable declared this way reads public final static double INTEREST_RATE = 0.05;
A named constant is a static member variable declared final. Because its value is fixed after initialization, it remains the same for as long as the program runs.
Each part of the declaration has a job. The access modifier public makes the constant visible to other code. The modifier static attaches the variable to the class rather than to any one object. The modifier final locks the value after initialization. The declared type, double, and the initial value, 0.05, complete the declaration.
The final modifier is not limited to member variables. It is legal on local variables, formal parameters, classes, and subroutines. The source notes, however, that it is most useful on member variables, because a named constant that many parts of a program depend on is where naming and locking pay off most.
What the Compiler Enforces
The guarantee that a final variable cannot be changed is enforced by the compiler, before the program runs. Attempting to reassign a final variable is a compile-time syntax error, not a run-time surprise. The program is never executed with the bad assignment, so the mistake is caught while the code is still being checked.
The flowchart shows the decision point. A reassignment to a non-final variable passes the check and proceeds. A reassignment to a final variable is stopped at compile time. This is why a reader can trust a named constant: no other statement in the program is allowed to alter it.
What do you think happens?
Suppose addInterest is written as shown earlier, and some other statement in the class says INTEREST_RATE = 0.06;. Does the program compile?
Reveal answer
No. The compiler reports a syntax error because INTEREST_RATE is final.
Reassigning a final variable is a compile-time error. The program does not run with the new value.
Naming Style for Constants
The recommended style for named constants is to write the whole name in upper case letters, using underscore characters to separate words when necessary. The interest rate becomes INTEREST_RATE. This is the style used throughout Java's standard classes, which define many named constants.
The upper-case convention is a signal to the reader. When you see INTEREST_RATE in a statement, you know immediately that you are looking at a fixed quantity with a name, not an ordinary variable that might be updated. Java's own library follows the same pattern. The Math class contains Math.PI, declared as a public final static variable of type double, and the Color class contains constants such as Color.RED and Color.YELLOW.
Enumerated Types Versus Integer Constants
Enumerated types extend the idea of named constants. An enumerated type definition lists the set of values a type may take. Consider a text alignment setting with three choices: LEFT, RIGHT, and CENTER. Each choice is a named constant, accessed as Alignment.LEFT, Alignment.RIGHT, and Alignment.CENTER.
- Alignment lists exactly three valid values
- Assigning a listed constant is accepted by the compiler
- Assigning an arbitrary integer is rejected
Technically, Alignment is a class, and its three constants are public final static members of that class. Defining an enumerated type therefore resembles defining three separate constants of type int. Before enumerated types were introduced, that was the standard approach, and many programs still use it.
The integer approach has a serious weakness. A variable of type int can be assigned any integer, and the computer has no way of knowing that the variable is meant to represent an alignment. An enumerated type closes that gap. The only values that can be assigned to an Alignment variable are the listed constants, and any attempt to assign an invalid value is a syntax error that the compiler detects. The source identifies this extra safety as one of the major advantages of enumerated types.
Changing a Constant in One Place
A constant cannot change while the program is running, but between runs you can edit its value in the source code, recompile, and the new value takes effect everywhere the constant is used. The feature that prevents change at run time is the same feature that makes change easy during maintenance.
Consider what happens when the bank changes its rate. If the literal 0.05 appears many times, the programmer must find every place it is used and change each one. That search is harder than it sounds, because the number 0.05 might also appear with other meanings in the same program, and a different number such as 0.025 might represent half the rate. If INTEREST_RATE is declared and used consistently, only the single line where it is initialized needs to change.
Mistakes Beginners Make with Constants
Common mistake Leaving a meaningless literal in the code
What it looks likeprincipal += principal * 0.05;Why it failsThe reader has to guess what 0.05 stands for, and the same literal may appear elsewhere with a different meaning.
Do this insteadDeclare public final static double INTEREST_RATE = 0.05; and write principal += principal * INTEREST_RATE;Common mistake Trying to reassign a final variable
What it looks likeINTEREST_RATE = 0.06;Why it failsA final variable cannot be changed after initialization, so this is a compile-time syntax error.
Do this insteadChange the value in the declaration and recompile, or use an ordinary variable if the value must change while the program runs.
Common mistake Declaring a running total as final
Why it failsA total that the program updates as it works must be allowed to change, so final would cause compile errors.
Do this insteadUse a plain variable for values the program modifies.
Common mistake Using lower-case names for constants
What it looks likedouble interestRate = 0.05; (declared final)Why it failsOrdinary naming hides the signal that this is a fixed quantity.
Do this insteadUse INTEREST_RATE so the reader sees a fixed, named quantity at a glance.
Common mistake Using a plain int where an enumerated type fits, which lets invalid values such as 7 be assigned to an alignment setting
Practice: Name the Constant
A program computes a shipping fee. The fee per kilogram is 2.5 and never changes during the run. Rewrite the line total = weight * 2.5; so that the rate has a meaningful name, following the upper-case constant style. Then state what the compiler does if a later statement tries to assign a new value to that name.
Hints
- Declare the rate with the modifiers public final static, a type, and a name in upper case with underscores.
- The compiler reports a compile-time syntax error for any reassignment of a final variable.
A program stores a day of the week as an int, where 0 means Monday and so on. Explain how an enumerated type would prevent the value 9 from being assigned to a day variable, and state at what stage the error is caught.
Hints
- Think about which values an enumerated type accepts.
- The check happens when the code is compiled, not when it runs.
Key Takeaways
- A named constant gives a meaningful name to a value that is meant to stay fixed for the whole program, so readers do not have to guess what a bare literal represents.
- Declaring a member variable as public final static with an initial value creates a named constant; reassigning it is a compile-time syntax error.
- Constants follow the upper-case convention with underscores, such as INTEREST_RATE, which signals a fixed quantity to the reader.
- An enumerated type restricts a variable to a fixed list of named constants, which an int constant cannot enforce.
- Because a constant is declared in one place, changing its value there updates every use after recompilation.