Skip to main content

Generic Methods

Just as you can define generic classes, you can also define Generic Methods.

A generic method introduces its own type parameters. This is incredibly useful when you want a method to be able to accept arguments of different types, but you don't necessarily want to make the entire class generic.


Syntax of a Generic Method

To declare a generic method, the type parameter section (like <E> or <T>) must appear before the method's return type.

public <E> void printArray(E[] elements) { ... }

Example: Printing Arrays of Different Types

Imagine you have an array of Integers, an array of Strings, and an array of Doubles. Without generics, you would have to write three separate, overloaded methods (one for each type) to print them.

With generic methods, you can write a single method to handle all of them!

public class LabGenericMethod1 {

// Generic method printArray
// <E> is declared before the void return type
public static <E> void printArray(E[] elements) {
for (E element : elements) {
System.out.print(element + " ");
}
System.out.println();
}

public static void main(String args[]) {
// Note: We use Wrapper classes because Generics don't work with primitives
Integer[] intArray = { 10, 20, 30, 40, 50 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
String[] stringArray = { "Java", "is", "awesome" };

System.out.print("Printing Integer Array: ");
printArray(intArray);

System.out.print("Printing Character Array: ");
printArray(charArray);

System.out.print("Printing String Array: ");
printArray(stringArray);
}
}

Output:

Printing Integer Array: 10 20 30 40 50
Printing Character Array: H E L L O
Printing String Array: Java is awesome

[!NOTE] In the example above, the compiler infers the type of E based on the arguments we pass to the method. When we pass intArray, E becomes Integer. When we pass stringArray, E becomes String.


Bounded Type Parameters in Methods

Sometimes, you want to restrict the kinds of types that are allowed to be passed to a type parameter. For example, a method that calculates the average of numbers should only accept numbers (Integer, Double, Float), not Strings.

To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound.

public class LabGenericMethod2 {

// <T extends Number> restricts T to Number or its subclasses
public static <T extends Number> void printDoubleValue(T number) {
// Because T is a Number, we can safely call Number methods!
System.out.println(number.doubleValue());
}

public static void main(String args[]) {
printDoubleValue(10); // Integer (extends Number) -> 10.0
printDoubleValue(4.5f); // Float (extends Number) -> 4.5

// printDoubleValue("Hello"); // COMPILE ERROR! String does not extend Number.
}
}