Q: What does the static keyword do? Where can it be used?

Answer:

static = belongs to the class, not to instances. One copy shared across all instances. Loaded when the class is loaded.

1. Static Variables (Class Variables)

class Counter {
    static int count = 0;   // shared across all instances
    int id;                 // per instance

    Counter() { id = ++count; }
}

new Counter();  // count=1
new Counter();  // count=2 — shared

2. Static Methods

class MathUtil {
    static int square(int x) { return x * x; }
}
MathUtil.square(5);  // call without instance

Rules:

  • Cannot access instance fields/methods (no this).
  • Cannot be overridden — hidden (resolved at compile time, not polymorphic).
  • Can be called via instance, but discouraged: obj.staticMethod().

3. Static Block

class Config {
    static final Map<String, String> MAP;
    static {
        MAP = new HashMap<>();
        MAP.put("env", "prod");
    }
}

Runs once at class load. Multiple blocks run top-to-bottom.

4. Static Nested Class

class Outer {
    static class Nested {
        // does NOT hold reference to Outer instance
    }
}
Outer.Nested n = new Outer.Nested();

vs. inner class (non-static) which holds implicit Outer.this reference.

5. Static Imports

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;

double r = sqrt(PI);  // no Math. prefix

Static Method Hiding vs Overriding

class Parent { static void hi() { System.out.println("parent"); } }
class Child extends Parent { static void hi() { System.out.println("child"); } }

Parent p = new Child();
p.hi();  // "parent" — static binding (hidden, not overridden)

Compare with instance methods — would print "child" (dynamic dispatch).

Common Pitfalls

  • Mutable static state = global state = thread-safety nightmare.
  • Static + Spring = bypass DI; static fields not injected by default.
  • Memory leaks: static collections keep references alive for class lifetime.
  • Test isolation: static state leaks across tests.

When to Use

  • Constants (public static final).
  • Pure utility functions (Math.max, Collections.sort).
  • Factory methods (List.of, Optional.of).
  • Singletons (carefully).

When to Avoid

  • Anything stateful that's not a constant.
  • Anything you want to mock in tests.
  • Replace with dependency injection where possible.