Can you write a generic method — and how does it differ from a generic class?
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.