Skip to content

4 · 32 · 5 min

Belonging to the class or to the object

Some data belongs to each object. Some belongs to the class as a whole. Choosing wrongly produces bugs that only appear with more than one user.

The difference

java
public class Order {
    private static int totalOrders = 0;   // one copy, shared by all
    private final int id;                  // one per object

    public Order() {
        this.id = ++totalOrders;
    }
}

Create a thousand orders and there are a thousand id fields and exactly one totalOrders.

A static method has no this and cannot touch instance fields, because there is no particular object to touch.

When static is right

A utility with no state: Math.max, Integer.parseInt.

A factory: LocalDate.of(2026, 9, 24), which reads better than a constructor and can return a cached instance.

A genuine constant: static final.

When it is wrong, and the reason

Mutable static state is shared by everything in the process, which makes it the default source of two problems.

Concurrency. Every thread touches the same field. totalOrders++ above is a race exactly as described in the operating systems course.

Testing. State left behind by one test is visible to the next, so tests pass alone and fail together, or pass in one order and fail in another. That is one of the most frustrating classes of flaky test because the failing test is rarely the guilty one.

java
// hard to test: nothing can substitute the real clock or the real database
public class Report {
    public static Report generate() {
        return new Report(Database.getInstance().query(), LocalDate.now());
    }
}

The static dependency cannot be replaced, so the test needs a real database and cannot control the date. Passing the dependencies in makes both trivial, which is the argument the dependency injection page develops.

Static is not a namespace

A class used only as a container for static methods is a namespace with extra steps. Some languages offer modules or free functions and those are usually the better expression. In Java, where everything must be in a class, a class of static utilities is idiomatic and should still be stateless.

InstanceStatic
Copiesone per objectone per class
Has thisyesno
Substitutable in testsyesno
Safe to mutatewith carerarely