Generic Methods in Java

Generic methods declare their own type parameters, independent of a class's type parameters. At each invocation, Java uses the arguments and target context to infer suitable types or checks explicitly supplied type arguments.

A generic method introduces type parameters immediately before its return type, such as `static <T> T first(List<T> values)`. The `T` belongs to the method itself, so the method can be generic even when its containing class is not.

Type inference usually lets callers omit explicit type arguments. For example, `identity(42)` infers `T` as `Integer`, while `identity("Java")` infers `T` as `String`. You can also provide the type explicitly with syntax such as `Utils.<String>identity("Java")` when inference is insufficient or clarity is useful.

A method can declare multiple type parameters, and those parameters can have bounds. For example, `<T extends Number>` restricts `T` to `Number` and its subclasses. A bounded parameter can then be used where the bound guarantees the required operations or members.

Generic methods are especially useful for reusable algorithms that should preserve relationships between input and output types. They differ from methods that merely accept or return wildcarded types: a named method type parameter can express relationships such as "the returned value has the same type as the argument."

Generic methods are checked by the compiler; Java generics use type erasure, so the type parameter does not normally create a distinct runtime method for every concrete type. This is why generic type information has important compile-time benefits but also some runtime limitations.

Key points

Interview questions

What is a generic method in Java?

A generic method declares one or more type parameters of its own. The parameters are written before the return type, for example `<T> T identity(T value)`. Java can infer the type arguments from a call such as `identity("hello")`. This lets one method remain type-safe for many concrete types without casts at the call site.

How does Java infer the type parameter of a generic method?

The compiler examines the method arguments and, where relevant, the target type of the invocation. It determines type arguments that make the invocation type-correct. For example, assigning `identity("x")` to a `String` variable supports `T` being `String`. If inference cannot find a suitable solution, the programmer may need to provide explicit type arguments or change the expression.

What is the difference between `<T>` and `?`?

`<T>` introduces a named type variable that can be reused within the method signature to express a relationship. A wildcard represents an unknown type and is useful when the exact type does not need to be named. For example, `<T> T copy(T value)` can state that the result has the same type as the input. By contrast, `List<?>` says only that the list contains some unknown type.

Why would you put a bound on a generic method type parameter?

A bound restricts which types can be used and tells the compiler what operations are guaranteed by that type. For example, `<T extends Number>` permits `T` to be a subtype of `Number`, allowing the method to use members provided by `Number`. The bound also causes invalid invocations to fail at compile time. Multiple bounds are possible when the language's bound rules are satisfied.

Can a generic method have the same type parameter name as its generic class?

Yes, a method can declare a type parameter with the same identifier as a class-level type parameter, but the method declaration then introduces a distinct type variable that shadows the class-level name within the method's scope. This is legal but often confusing. Good code generally uses distinct names or avoids unnecessary shadowing. The important point is that identical names do not make the two type variables identical.