← Back to Advanced Java Course | Chapter 1: Generics | Lesson 3 of 4

Java Generic Methods

A generic method is a method that works with many types by leaving the type as a blank, like a machine that can wrap any shape of gift. Java figures out the type from what you give it.
Syntax
java
public <T> returnType methodName(T parameter) {
    // body
}

methodName(argument);

What is a Generic Method?

A generic method declares its own distinct type parameters inside its own signature, separate from any type parameters the enclosing class might have. This lets a single method accept and work with any data type, even inside a class that isn't generic at all.

Example: What is a Generic Method?

java
// Define the class Main
public class Main {
	static <T> void show(T item) {
		// Print a line to the console
		System.out.println("Value: " + item);
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		show("text");
		show(42);
	}
}

Declaring Type Parameters

To define a generic method, place your type parameters inside angle brackets, such as <T>, right before the method's return type in the declaration line. This tells the compiler the parameter is scoped to that one method call, not the whole class.

Example: Declaring Type Parameters

java
// Define the class Main
public class Main {
	static <T> T identity(T value) {
		// Send value back to the caller
		return value;
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Print a line to the console
		System.out.println(identity("scoped to this method"));
	}
}

Bounded Type Methods

You can restrict a generic method's parameters using bounded types, ensuring the method only accepts subclasses of a specific class or implementers of a specific interface. This is especially useful when the method's body needs to call a method that only exists on that bound, like compareTo() on a Comparable.

Example: Bounded Type Methods

java
// Define the class Main
public class Main {
	static <T extends Comparable<T>> T max(T a, T b) {
		// Send a.compareTo(b) > 0 ? a : b back to the caller
		return a.compareTo(b) > 0 ? a : b;
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Print a line to the console
		System.out.println(max(5, 9));
	}
}

Multiple Method Parameters

Generic methods can declare multiple type parameters at once, separated by commas inside the angle brackets, such as <T, U>, when the method needs to relate two different input types together. A classic example is a method that copies elements from one typed list into a differently-typed destination list.

Example: Multiple Method Parameters

java
// Import java.util.List so it can be used by its short name
import java.util.List;
// Import java.util.ArrayList so it can be used by its short name
import java.util.ArrayList;
// Define the class Main
public class Main {
	static <T, U> void copyLabeled(List<T> source, List<U> dest, U label) {
		for (T item : source) dest.add(label);
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		List<Integer> nums = List.of(1, 2, 3);
		// Create a new ArrayList object and store it in labels
		List<String> labels = new ArrayList<>();
		copyLabeled(nums, labels, "n");
		// Print a line to the console
		System.out.println(labels);
	}
}

Type Inference

You do not need to specify type parameters explicitly when calling most generic methods, since the Java compiler automatically infers the data type from the arguments you pass in. This type inference is what keeps generic method calls looking just as clean as ordinary method calls.

Example: Type Inference

java
public class Main {
	static <T> T pick(T a, T b) {
		return a;
	}
	public static void main(String[] args) {
		String result = pick("first", "second"); // no <String> needed, inferred
		System.out.println(result);
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting to declare <T> before the return type, as in static void show(T item), which fails with a 'cannot find symbol' error for T.
  2. Calling a.compareTo(b) on an unbounded T, which does not compile; declare <T extends Comparable<T>> to use it.
  3. Passing an int[] to a method taking T[], which does not work because T must be a reference type; use Integer[].
🔒

Chapter Quiz — Complete all 4 topics to unlock

0/4 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.