Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Java Dictionary

  1. Home
  2. Java Dictionary
  3. Generics (<T>)

Generics (<T>)

A mechanism for defining classes and methods that work with any type by using type parameters. Collection classes (such as List<T>) are prime examples, and generics guarantee type safety at compile time (Java 5 and later).

Syntax

// Defines a generic class.
class Box<T> {
    private T value;
    Box(T value) { this.value = value; }
    T get() { return value; }
}

// Defines a generic method.
static <T> T firstElement(List<T> list) {
    return list.get(0);
}

// Sets an upper bound on the type parameter (T must be a subtype of Number).
class NumericBox<T extends Number> {
    T value;
    double doubleValue() { return value.doubleValue(); }
}

// Wildcard: represents an unknown type.
void printList(List<?> list) { /* accepts a List of any type */ }

// Upper-bounded wildcard: accepts subtypes of Number.
double sumList(List<? extends Number> list) {
    return list.stream().mapToDouble(Number::doubleValue).sum();
}

// Lower-bounded wildcard: accepts supertypes of Integer.
void addNumbers(List<? super Integer> list) {
    list.add(42);
}

Common Notation

NotationDescription
<T>Type parameter. Represents an arbitrary type. By convention, T (Type), E (Element), K (Key), and V (Value) are commonly used.
<T extends Number>Sets an upper bound on the type parameter. T is restricted to Number or its subclasses.
<?>Wildcard. Represents an unknown type. Used for read-only operations.
<? extends T>Upper-bounded wildcard. Accepts subtypes of T (used for output/reading).
<? super T>Lower-bounded wildcard. Accepts supertypes of T (used for input/writing).

Sample Code

import java.util.*;

// Uses the generic class.
Box<String> strBox = new Box<>("Hello");
Box<Integer> intBox = new Box<>(42);
System.out.println(strBox.get()); // Prints "Hello".
System.out.println(intBox.get()); // Prints "42".

// Uses the generic method.
List<String> names = List.of("Alice", "Bob", "Carol");
System.out.println(firstElement(names)); // Prints "Alice".

// Uses a type bound to restrict to subclasses of Number.
NumericBox<Integer> nb = new NumericBox<>();
nb.value = 100;
System.out.println(nb.doubleValue()); // Prints "100.0".

// Uses wildcards to process lists of multiple types.
List<Integer> ints = List.of(1, 2, 3, 4, 5);
List<Double>  dbls = List.of(1.5, 2.5, 3.5);
System.out.println(sumList(ints)); // Prints "15.0".
System.out.println(sumList(dbls)); // Prints "7.5".

Notes

Using generics lets you write type-safe code without casting to Object. Since only String values can be added to a List<String>, runtime ClassCastException errors are prevented.

Java generics are implemented through a mechanism called type erasure: type information is removed after compilation and replaced with Object. As a result, you cannot check a generic type parameter with instanceof at runtime, nor create an instance with new T().

For combining lambda expressions with generics, see Predicate / Function / Consumer / Supplier. For working with collection classes, refer to the corresponding pages.

If you find any errors or copyright issues, please .