# 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.

```java
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:

```java
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`:

```java
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.

```java
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.

```java
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.

```java
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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://tingreavinash.gitbook.io/the-tech-toolbox/notes/java-fundamentals/generics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
