Blank Final and Static Final Variables
A PNR number is fixed for each ticket, but it isn't known until the ticket is booked: every ticket has a different one. So it can't be a constant written into the class, yet it must never change once set. Java handles this with a blank final: a final field declared without a value, which each constructor must assign exactly once.
Blank Final Instance Fields
public class Tickets {
static class Ticket {
final String pnr;
final String passenger;
int berth;
Ticket(String pnr, String passenger) {
this.pnr = pnr;
this.passenger = passenger;
}
}
public static void main(String[] args) {
Ticket a = new Ticket("4512345678", "Navika Anamaneni");
Ticket b = new Ticket("4598765432", "Advitha Anamaneni");
a.berth = 23;
a.berth = 31;
System.out.println(a.pnr + " " + a.passenger + ", berth " + a.berth);
System.out.println(b.pnr + " " + b.passenger);
}
}4512345678 Navika Anamaneni, berth 31
4598765432 Advitha AnamaneniHow it works
- Lines 3 and 4:
pnrandpassengerare blank finals:final, but no value where they're declared. - The constructor assigns each one exactly once. Each ticket gets its own value, fixed for life.
berthisn't final, so it can change (lines 16 and 17).
Try it yourself: add a.pnr = "1111111111"; in main. Read the error.
What the Compiler Checks
If any constructor can finish without assigning it:
Blank.java:1: error: variable pnr might not have been initialized
class Ticket { final String pnr; Ticket() {} }
^With several constructors, chaining them to one constructor that assigns all blank finals (see "Constructor Overloading and Constructor Chaining") makes it easy to get right.
Static Final: Class Constants
| Kind | Declared | Assigned | One value per |
|---|---|---|---|
| Final instance field | final String pnr; | In each constructor (or an instance block) | Object |
| Static final (constant) | static final int MAX_SEATS = 72; | At declaration | Class |
| Blank static final | static final String BUILD; | In a static block | Class |
A blank static final is useful when the value needs a calculation or a check:
public class Settings {
static class AppInfo {
static final String BUILD;
static {
int year = 2026, month = 11;
BUILD = "PoolString-" + year + "." + month;
}
}
public static void main(String[] args) {
System.out.println(AppInfo.BUILD);
}
}PoolString-2026.11Compile-Time Constants
A static final of a primitive or String type, assigned a constant expression at declaration (static final int MAX = 72;), is a compile-time constant. The compiler copies its value straight into the code that uses it. Two consequences:
- It can be used in
caselabels of aswitch. - If you change it, classes that use it must be recompiled to see the new value.
Common Mistakes
Forgetting to assign a blank final in one constructor. The compiler reports might not have been initialized.
Assigning it twice. For example in an instance block and again in the constructor: variable pnr might already have been assigned.
Making a per-object value static final. A static final has one value for the whole class; a PNR must be a final instance field.
Interview Corner
What is a blank final variable?
A final variable declared without an initializer. A blank final instance field must be assigned exactly once in every constructor or in an instance initializer; a blank static final must be assigned exactly once in a static block. After that, it can't change.
Practice
- Easy: Add a blank final
aadhaarLast4to aCustomerclass and set it in the constructor. - Harder: Create a class with two constructors and a blank final
id. Make both constructors set it by chaining to one of them.
Key Takeaways
Was this tutorial helpful?