Java Generic Methods
A generic method declares its own type parameter before the return type. The method then works for every type, and the compiler infers the type from each call.
First of a text list
first takes a List<T> and answers its first element. The call passes a list of names.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> T first(List<T> list) {
return list.get(0);
}
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Ana");
names.add("Ben");
System.out.println(first(names));
}
}First of a number list
The same method now takes a list of integers. T becomes Integer for this call alone, and the answer supports arithmetic.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> T first(List<T> list) {
return list.get(0);
}
public static void main(String[] args) {
ArrayList<Integer> scores = new ArrayList<>();
scores.add(40);
scores.add(70);
scores.add(55);
System.out.println(first(scores));
System.out.println(first(scores) + 5);
}
}Inference at the call
Both results land in typed variables. The compiler matches each variable type with the element type of the list passed in.
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> T first(List<T> list) {
return list.get(0);
}
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Ana");
names.add("Ben");
ArrayList<Integer> scores = new ArrayList<>();
scores.add(40);
scores.add(70);
String word = first(names);
Integer number = first(scores);
System.out.println(word);
System.out.println(number);
}
}Example
import java.util.ArrayList;
import java.util.List;
public class Main {
static <T> T first(List<T> list) {
return list.get(0);
}
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("Ana");
names.add("Ben");
ArrayList<Integer> scores = new ArrayList<>();
scores.add(40);
scores.add(70);
ArrayList<Double> prices = new ArrayList<>();
prices.add(9.5);
prices.add(4.5);
System.out.println(first(names));
System.out.println(first(scores) + 10);
System.out.println(first(prices));
}
}Key points
- The <T> before the return type declares the type parameter of the method.
- The compiler infers T from the argument, so call sites write no type.
- One first method answers the first element of a string list and of a number list.
- A generic method can live on a plain class that is not generic itself.
In this example, one first method serves three list types in a single program. Inference fills T separately for each call, so each answer arrives in its own type.
Note
A generic method can also be called with an explicit type, but inference makes that rare.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
In the call first(names), where names is a List<String>, how does the compiler know what T is?