Syntax
class ClassName<T> {\n // T can be used as a type\n}Examples
Basic Generic Class
A class that works with any type, specified when it is used.
public class Box<T> {
private T content;
public void set(T content) {
this.content = content;
}
public T get() {
return content;
}
}
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
System.out.println(stringBox.get()); // Hello
Box<Integer> intBox = new Box<>();
intBox.set(42);
System.out.println(intBox.get()); // 42Generic Methods
A single method can be generic even inside a non-generic class.
public class Utils {
public static <T> void printArray(T[] array) {
for (T item : array) {
System.out.println(item);
}
}
public static void main(String[] args) {
Integer[] numbers = {1, 2, 3};
String[] words = {"a", "b", "c"};
printArray(numbers);
printArray(words);
}
}Multiple Type Parameters
A generic class or interface can have more than one type parameter, like Map<K, V>.
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
@Override
public String toString() {
return key + " -> " + value;
}
}
Pair<String, Integer> pair = new Pair<>("age", 21);
System.out.println(pair); // age -> 21Bounded Type Parameters
Restricting a generic type to subtypes of a given class or interface with 'extends'.
public class NumberBox<T extends Number> { // T must be Number or a subtype
private T value;
public NumberBox(T value) {
this.value = value;
}
public double doubled() {
return value.doubleValue() * 2; // Number guarantees doubleValue() exists
}
}
NumberBox<Integer> box = new NumberBox<>(10);
System.out.println(box.doubled()); // 20.0
// NumberBox<String> invalid = new NumberBox<>("text"); // Error - String isn't a NumberBest practices
- Use generics whenever a class or method's logic is the same regardless of type, to avoid duplicating code for each specific type
- Follow Java naming conventions for type parameters: T for a general type, E for an element, K/V for a key/value pair
- Use bounded type parameters (<T extends Number>) when your generic code needs to call methods specific to a certain family of types
- Prefer generics over using Object and manual casting - generics catch type errors at compile time instead of causing a ClassCastException at runtime
Runtime & versions
Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
Java Language Specification