Static Methods in Java
A static method belongs to the class, not to any instance. You call it via ClassName.method(). It has no access to instance fields or methods because no this exists. Use static methods for pure utilities β Math.max, Collections.sort, Files.readString.
Defining one
public class MathUtils {
public static int square(int n) { return n * n; }
public static double clamp(double v, double lo, double hi) {
return Math.max(lo, Math.min(hi, v));
}
}
MathUtils.square(5); // 25
Static methods can't use this
public class Counter {
private int count;
public static void bad() {
count++; // β no enclosing instance
}
public void good() { // instance method β has `this`
count++;
}
}
Factory methods
public final class Money {
private final BigDecimal amount;
private final Currency currency;
private Money(...) { ... }
public static Money usd(BigDecimal amount) {
return new Money(amount, Currency.getInstance("USD"));
}
public static Money zero(Currency c) { return new Money(BigDecimal.ZERO, c); }
}
var m = Money.usd(new BigDecimal("10.50"));
Static import
import static java.lang.Math.*;
import static org.assertj.core.api.Assertions.assertThat;
double r = sqrt(pow(x, 2) + pow(y, 2));
assertThat(value).isEqualTo(42);
Use static imports for DSL-like code (assertions, math). Don't abuse them β sort(list) without context is less clear than Collections.sort(list).
Static methods aren't polymorphic
class A { public static String who() { return "A"; } }
class B extends A { public static String who() { return "B"; } }
A a = new B();
a.who(); // "A" β resolved by compile-time type
If you need polymorphic dispatch, use an instance method.
Downsides
- Harder to test β can't mock
Math.max. For code you need to swap in tests, prefer an injected dependency. - No inheritance β can't override, only hide.
- Encourages global state β static methods often pair with static fields, and that path leads to singletons and threading nightmares.
Common mistakes
- Static helper that really wants instance state β refactor to a regular class with a constructor.
- Using static methods for everything β makes testing harder. Reserve for truly pure utilities.
- Static state in web apps β shared across all requests, hard to reason about under load.
Related
Pillar: Java methods. See also static keyword, constructors.