Can you write a generic method — and how does it differ from a generic class?

7 minintermediategeneric-methodsgenerics

Quick Answer

A generic method declares its own type parameter(s) in angle brackets before the return type, scoped to just that method call, independent of whether the enclosing class is generic. A generic class declares its type parameter(s) on the class itself, and every non-static method/field implicitly uses that same parameter; static methods can't use the class's type parameter and must declare their own if they need generics.

Detailed Answer

A generic method introduces its own type parameter, declared right before the return type, independent of any type parameter the enclosing class might have:

public class Utils {
    public static <T> T firstNonNull(T a, T b) {
        return a != null ? a : b;
    }
}
Utils.<String>firstNonNull("x", "y"); // explicit, though usually inferred:
Utils.firstNonNull("x", "y");

This is distinct from a generic class, where the type parameter is declared on the class and shared by all its (non-static) members:

public class Box<T> {
    private T value;
    public void set(T value) { this.value = value; }
    public T get() { return value; }
}
Box<String> box = new Box<>();

Key difference in practice: static methods cannot use the class's type parameter (T in Box<T>), because a static method exists independently of any particular parameterized instance — it doesn't know which T to use. If a static method needs its own generic type, it must declare one of its own, exactly like a standalone generic method:

public class Box<T> {
    // static <T> T get() { ... } // wrong — this T shadows/hides the class's T
    public static <U> Box<U> of(U value) {
        Box<U> b = new Box<>();
        b.set(value);
        return b;
    }
}

Generic methods are common as utility/factory methods (Collections.emptyList(), List.of(...), Comparator.comparing(...)) that need their own type parameter regardless of any surrounding class's generics.