Instance Variables in Java β Fields
An instance variable β or field β is a variable declared inside a class body, outside any method, and without the static keyword. Each object gets its own copy of every instance field. Fields hold the object's state.
Declaration and initialisation
public class BankAccount {
private final String owner; // must be set in constructor
private BigDecimal balance = BigDecimal.ZERO; // inline initialiser
public BankAccount(String owner) {
this.owner = owner;
}
}
Default values
Unlike local variables, fields have sensible defaults:
| Type | Default |
|---|---|
boolean | false |
byte, short, int, long | 0 |
float, double | 0.0 |
char | '\u0000' |
Any reference (String, List, etc.) | null |
Initialisation order
- The object is allocated; all fields set to their default.
- Parent constructor runs (explicit or implicit
super(...)). - Instance initialiser blocks and inline field initialisers run top-to-bottom.
- The constructor body runs.
public class Foo {
private int a = 1;
{ System.out.println("init block, a=" + a); }
private int b = 2;
public Foo() { System.out.println("ctor, b=" + b); }
}
// Output: "init block, a=1" then "ctor, b=2"
this.field vs field
public User(String name) {
this.name = name; // disambiguate field from parameter
}
public String description() {
return name; // unambiguous β no parameter shadows
}
Best practices
- Always
privateunless there's a reason not to. - Prefer
finalβ immutable fields are safer and can be safely shared across threads. - Defensive copies β if a field is a mutable collection taken from outside, copy it:
this.items = List.copyOf(items);. - Records for data β use a record instead of a class with a long field list + constructor + getters.
Common mistakes
- Public fields β bypass encapsulation.
- Non-final fields that never change after construction β add
final. - Mutable fields in a class that appears in
HashSet/HashMapkeys β changing them corrupts lookups.
Related
Pillar: Variables in Java. See also static variables, encapsulation, records.