Constants in Java

Naveen AnamaneniUpdated · 5 min read

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"

Booking.java▶ Try it
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));
    }
}
Output
Seats per coach: 72
Fare with GST: Rs. 590

How it works

  1. Lines 2 and 3 are constants: static final fields. static means one copy for the class; final means the value can't change.
  2. Line 6 is a final local variable. It works like any local, except it can't be reassigned.
  3. 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:

Compiler output
Final1.java:4: error: cannot assign a value to final variable MAX_SEATS
        MAX_SEATS = 80;
        ^
1 error

Assign 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:

Discount.java▶ Try it
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));
    }
}
Output
You pay: Rs. 1100

Each 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:

Note.java▶ Try it
public class Note {
    public static void main(String[] args) {
        final StringBuilder note = new StringBuilder("Paid");
        note.append(" via UPI");
        System.out.println(note);
    }
}
Output
Paid via UPI

Line 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 constantWith a constant
if (seats > 72) in ten placesif (seats > MAX_SEATS)
What does 72 mean? The reader has to guessThe name explains it
Rule changes to 80: find and fix all tenChange 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

  1. 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.
  2. Harder: Write a program with a final variable ticketClass that is set to "AC" or "Sleeper" inside an if, depending on a fare. Show that it compiles only when every path assigns it exactly once.

Quick check: Constants

4 questions
1What does final do to a variable?
2Which is the conventional way to declare a constant?
3final StringBuilder sb = new StringBuilder("A"); Which line compiles?
4What is a "magic number"?

Key Takeaways

Was this tutorial helpful?

Lesson 33 of 482