Skip to content
Theory · Classes and objects · lesson 7 of 10

static: shared by all

As you already know, a method marked static belongs to the blueprint itself, not to a house. Fields can be like that too. Imagine the blueprint has a line saying "houses built", and each crew adds one to it after building. There is one such line for the whole blueprint. If each house had its own, every house would say "1".

A program often needs a shared value like this: how many objects were created, which number to give the next one. Let's see how to do it:

JAVA
public class Main {
    public static void main(String[] args) {
        House a = new House();
        House b = new House();
        System.out.println(House.count); // 2
    }
}

class House {
    static int count;
    int number;
    House() {
        number = ++count;
    }
}

Let's go through the program step by step:

  1. static int count; is one field for the whole class House, and it holds 0 from the start.
  2. int number; is an ordinary field: each house has its own.
  3. The constructor runs number = ++count;. The expression ++count first adds one to the shared count and then gives the new value, which goes into this house's number.
  4. The first house gets number 1, the second gets 2, and after two new calls count is 2.
  5. House.count reads the field through the class name and prints 2.

The houses have different numbers, but the counter is shared:

JAVA
System.out.println(a.number); // 1
System.out.println(b.number); // 2
new House();
System.out.println(House.count); // 3

The line new House(); builds a house and stores the reference nowhere. That is allowed: the constructor still runs, and count grows to 3.

A static field

A static field is a field marked static: there is one for the whole class, however many objects there are. Let's compare the two kinds of fields:

An object's fieldA static field
Declarationint number;static int count;
How many copiesone in each objectone for the whole class
How to reach it from outsidethrough an object: a.numberthrough the class: House.count
When it appearswith each newwhen the JVM loads the class, before the first object

Inside its own class, a static field is reached by its bare name, like count in the constructor. This is why the fields and methods next to main have been written with static so far. Nobody created an object of the class Main, so only what belongs to the class itself could be used.

Here the blueprint picture is not exact. Only the crew corrects the line on a real blueprint, but a static field without private can be changed by any code in the program: House.count = 100; compiles.

A static method

A static method belongs to the class too, and you call it through the class name: Math.addExact(2, 3) is a static method of the class Math. There is no object in such a call, and so there is no this either. That is why a static method cannot read an object's field:

JAVA
class House {
    static int count;
    int number;
    static void show() {
        System.out.println(number); // ✗
    }
}
TEXT
error: non-static variable number cannot be referenced from a static context

The program does not compile. The call House.show() does not say which house it is about, so whose number to print is unknown. But show can read count: that field is one for the whole class. A static method works with an object's field only if it gets the object itself, as a parameter or through new.

Interviewers often ask why a static method cannot reach an object's field. The answer: a static method has no this, that is, no object whose field it could read.

Common mistake

The compiler says non-static variable … cannot be referenced from a static context, and the field is made static to make the error go away. The error goes, and so does the meaning of the field:

JAVA
public class Main {
    public static void main(String[] args) {
        House a = new House("red");
        House b = new House("blue");
        System.out.println(a.color); // blue
    }
}

class House {
    static String color; // ✗
    House(String color) {
        this.color = color;
    }
}

The program prints blue, although the house a was built red. The field color is one for the whole class, and the second constructor overwrote it. Plain javac says nothing, and only javac -Xlint:all warns that a static field is reached through an object. A color belongs to a particular house, so static has no place here: String color;.

Key points

  • A static field is one for the whole class: all objects share it, and from outside you reach it through the class, House.count.
  • A field without static is each object's own: a.number and b.number hold different numbers.
  • A static method has no this, so it can read an object's field only through a reference to the object.
  • static on a field that should belong to each object makes it shared: every house gets one color.