Constants in Java
Some numbers in a program should never change: the number of seats in a sleeper coach, the GST rate, the number of days in a week. If someone accidentally writes MAX_SEATS = 80 somewhere, you want the compiler to stop them, not discover it in production. In Java, the word final makes a variable that can be assigned only once.
final Means "Assign Once"
public class Booking {
static final int MAX_SEATS = 72;
static final int GST_PERCENT = 18;
public static void main(String[] args) {
final int baseFare = 500;
int gst = baseFare * GST_PERCENT / 100;
System.out.println("Seats per coach: " + MAX_SEATS);
System.out.println("Fare with GST: Rs. " + (baseFare + gst));
}
}Seats per coach: 72
Fare with GST: Rs. 590How it works
- Lines 2 and 3 are constants:
static finalfields.staticmeans one copy for the class;finalmeans the value can't change. - Line 6 is a
finallocal variable. It works like any local, except it can't be reassigned. - Line 7 uses both. GST on Rs. 500 at 18% is Rs. 90, so the total is Rs. 590.
Try it yourself: add the line MAX_SEATS = 80; inside main and compile. Read the error.
What the Compiler Says
Trying to change a final variable is a compile error, so the mistake never reaches a running program:
Final1.java:4: error: cannot assign a value to final variable MAX_SEATS
MAX_SEATS = 80;
^
1 errorAssign Later, but Only Once
A final variable doesn't have to get its value on the same line. It must get exactly one value before it's used:
public class Discount {
public static void main(String[] args) {
int amount = 1200;
final int discount;
if (amount >= 1000) {
discount = 100;
} else {
discount = 0;
}
System.out.println("You pay: Rs. " + (amount - discount));
}
}You pay: Rs. 1100Each path through the if assigns discount exactly once, so the compiler accepts it. If one path forgot to assign it, or assigned it twice, the code wouldn't compile.
A final Reference Can Still Change Its Object
final locks the variable, not the object it points to. With a reference type, you can't point the variable at a different object, but you can still change the object itself:
public class Note {
public static void main(String[] args) {
final StringBuilder note = new StringBuilder("Paid");
note.append(" via UPI");
System.out.println(note);
}
}Paid via UPILine 4 changes the object's contents, which is allowed. Writing note = new StringBuilder("Refund"); would be a compile error. Making the object itself unchangeable is a different idea, immutability, covered in "How to Create an Immutable Class in Java".
Why Use Constants
| Without a constant | With a constant |
|---|---|
if (seats > 72) in ten places | if (seats > MAX_SEATS) |
| What does 72 mean? The reader has to guess | The name explains it |
| Rule changes to 80: find and fix all ten | Change one line |
A bare number like 72 in the middle of code is often called a magic number. Give it a name.
Common Mistakes
Thinking final makes an object read-only. It only stops the variable being reassigned, as the StringBuilder example shows.
Naming a local final variable in capitals. final int BASE_FARE inside a method compiles, but capitals signal a class-level constant. Use camelCase for locals.
Forgetting static on a constant. final int MAX_SEATS = 72; as a field gives every object its own copy of the same number. Make class-wide constants static final.
Practice
- Easy: Create constants for the number of days in a week and the number of hours in a day, and print the number of hours in a week.
- Harder: Write a program with a
finalvariableticketClassthat is set to"AC"or"Sleeper"inside anif, depending on a fare. Show that it compiles only when every path assigns it exactly once.
Key Takeaways
Was this tutorial helpful?