What is the difference between a static member and an instance member in Java, in terms of memory, lifetime and access?
An instance member belongs to an object. Each object gets its own copy of an instance field, and the field lives exactly as long as that object. An instance method can only be called through a reference, and it has a this pointing at the object it was invoked on.
A static member belongs to the class. There is exactly one copy of a static field for the whole class, it is created when the class is initialised rather than when an object is created, and it lives until the class is unloaded. A static method has no this at all, which is why it cannot touch instance state, and it can be called without creating an object.
The memory picture is worth being concrete about. A static int occupies four bytes once, in the class metadata area. An instance int occupies four bytes inside every object, so a class with a thousand instances spends four thousand bytes on that field, plus the cost of the reference to each object in whatever holds them.
public class Main {
public static void main(String[] args) {
Counter a = new Counter();
Counter b = new Counter();
System.out.println("instance counter: " + a.counter);
a.counter = 5;
System.out.println("after a.counter = 5:");
System.out.println(" a.counter = " + a.counter);
System.out.println(" b.counter = " + b.counter);
System.out.println("static counter : " + Counter.created);
Counter.created++;
System.out.println("after one bump : " + Counter.created);
System.out.println("seen from b too : " + b.created);
}
}
class Counter {
int counter; // one per object
static int created = 0; // one per class
Counter() {
created++;
}
}The output shows both behaviours at once. Setting a.counter to 5 leaves b.counter at zero, because each object owns its own field. Incrementing Counter.created is immediately visible through b, because there is only one static counter in the class.
Access rules follow from this. A static member is reachable through the class name, and also through an instance reference for compatibility, but the class name is the honest way to write it. An instance member is reachable only through a reference. And a static method cannot reference an instance field, because at the moment it runs there may be no object at all.