Generics

Generics

Generics are a powerful feature of the Java programming language that allow for type-safe collections and methods. Generics enable code to be written that can work with different types of objects, without sacrificing type safety. The following is a detailed cheatsheet for generics in Java.

Type Parameters

Type parameters are used to define generic types in Java. They are specified within angle brackets (<>) and are typically represented by a single capital letter. For example, T is commonly used to represent a type parameter.

public class Example<T> {
    private T value;

    public Example(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
}

Generic Classes

Generic classes are classes that are parameterized by one or more type parameters. The type parameter can be used in the class definition to specify the type of data the class will handle. For example, a generic List class could be defined as follows:

public class List<T> {
    private T[] data;

    public List(int size) {
        data = (T[]) new Object[size];
    }

    public void add(T element) {
        // add element to data array
    }

    public T get(int index) {
        // return element at specified index
    }
}

Generic Methods

Generic methods are methods that use type parameters to specify the type of data they can work with. Type parameters can be declared either before or after the return type of the method. For example, the following method takes an array of type T and returns a List of type T:

public static <T> List<T> arrayToList(T[] array) {
    List<T> list = new ArrayList<>();
    for (T element : array) {
        list.add(element);
    }
    return list;
}

Wildcards

Wildcards are used in Java to represent unknown types. The ? symbol is used to represent a wildcard. Wildcards can be used to specify a generic type parameter that can be any type.

public static void printList(List<?> list) {
    for (Object element : list) {
        System.out.println(element);
    }
}

Bounded Type Parameters

Bounded type parameters are used to restrict the types that can be used as a generic type parameter. The extends keyword is used to specify a upper bound, while the super keyword is used to specify a lower bound.

public static <T extends Comparable<T>> T getMax(T[] array) {
    T max = array[0];
    for (int i = 1; i < array.length; i++) {
        if (array[i].compareTo(max) > 0) {
            max = array[i];
        }
    }
    return max;
}

Type Erasure

Type erasure is a feature of Java that removes all generic type information at runtime. This is done for performance reasons, but can lead to certain limitations when working with generics.

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
// Type erasure means that the following code will not compile:
// int value = list.get(0);
// Instead, you must cast the value to an Integer:
Integer value = list.get(0);

Conclusion

Generics are an important feature of the Java programming language that enable type-safe collections and methods. By using type parameters, generic classes and methods can work with different types of objects while maintaining type safety. Wildcards and bounded type parameters provide additional flexibility for generic programming. Type erasure is a limitation of generics, but

Last updated