Skip to content
Part IA Michaelmas Term

Static Methods

What Static Methods Are

A static method belongs to the class, not to an instance. It is called on the class name and has no implicit this reference. This means a static method cannot directly access instance (non-static) fields or call instance methods — there is no “current object” to operate on.

public class MathUtils {
    public static double average(double a, double b) {
        return (a + b) / 2.0;
    }
}

double result = MathUtils.average(10.5, 20.3);

No MathUtils object is created. The method is called purely through the class.

The Static Context Rule

The most important rule about static methods — and a favourite Tripos trap — is:

From a static context, you can only reference other static members directly. To access instance members, you need an explicit object reference.

public class Counter {
    private int value = 0;                    // instance field
    private static int totalCount = 0;         // static field

    public void increment() {                  // instance method
        this.value = this.value + 1;           // OK — instance context
        totalCount = totalCount + 1;            // OK — static field accessible from instance
    }

    public static int getTotalCount() {        // static method
        return totalCount;                      // OK — static field
    }

    public static void reset() {               // static method
        value = 0;                              // COMPILE ERROR! Cannot access instance field
        this.value = 0;                         // COMPILE ERROR! No 'this' in static context
        increment();                             // COMPILE ERROR! Cannot call instance method
    }
}

The fix is to create an instance and call methods on it, or to make the method non-static:

public static void reset(Counter c) {
    c.value = 0;   // OK — explicit object reference provided
}

Common Uses of Static Methods

Utility Methods

Pure functions that operate only on their parameters and have no side effects are natural candidates for static methods. The JDK is full of examples:

Math.sqrt(16.0);
Math.max(3, 7);
Collections.sort(myList);
Arrays.copyOf(original, newLength);

These methods do not need object state — they are computational building blocks.

Factory Methods

A static method that creates and returns instances of a class is a factory method. This is often cleaner than overloaded constructors because the method name can describe intent:

public class LocalDate {
    public static LocalDate of(int year, int month, int day) {
        return new LocalDate(year, month, day);
    }

    public static LocalDate now() {
        return new LocalDate(/* current system date */);
    }

    public static LocalDate parse(String text) {
        return new LocalDate(/* parse from ISO format */);
    }
}

LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(2000, 3, 15);
LocalDate parsed = LocalDate.parse("2025-07-15");

Factory methods can also return subtypes, cache instances, or enforce invariants in ways that constructors cannot because constructors must always return a new instance of the exact class.

The main Method

public static void main(String[] args) must be static because the JVM calls it before any objects exist. There is no instance of the containing class at the moment the program starts — the JVM would have no object to call an instance method on.

Static Factories for Immutable Value Types

When a value type is immutable (like String or Integer), static factory methods can offer instance-controlled creation:

Integer.valueOf(42);    // may return a cached instance
Integer.parseInt("42"); // returns a primitive, not an Integer object

Contrast with Instance Methods

Instance MethodStatic Method
Called onAn object reference obj.method()The class name Class.method()
Has this?Yes — refers to the receiver objectNo — no receiver
Accesses instance fields?YesNo (directly)
Accesses static fields?YesYes
Can be overridden?Yes (unless final)No (hidden, not overridden)
Typical useBehaviour that depends on an object’s stateBehaviour that is independent of any particular object

Static Import

The import static statement lets you use static members without qualifying them with the class name:

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

double circumference = 2 * PI * radius;
double root = sqrt(16.0);

Use sparingly — it can make code harder to read when the origin of a name is not obvious. import static org.junit.Assert.* is common in test code.

Common Tripos Traps

Static Method Overriding (Which Does Not Exist)

class Parent {
    public static void greet() {
        System.out.println("Hello from Parent");
    }
}

class Child extends Parent {
    public static void greet() {
        System.out.println("Hello from Child");
    }
}

Parent p = new Child();
p.greet();  // Prints "Hello from Parent" — static dispatch, not dynamic!

Static methods are resolved at compile time based on the declared type of the variable, not the runtime type of the object. The @Override annotation does not compile on static methods. This is called hiding, not overriding.

Calling Non-Static from Static

Every exam will test this in some form. If you see a static method attempting to access an instance field or call an instance method without an explicit object reference, it is a compile error.

The Implicit ‘this’ in Inner Classes

An inner (non-static nested) class has an implicit reference to the enclosing instance. Its methods can access the enclosing instance’s fields. But a static nested class has no such reference — it behaves like a top-level class and can only access static members of the enclosing class.