Skip to content

Java Generics

In the world of programming, Java Generics are like those labels. They help Java programmers write code that can work with different types of data, just like those shelves can hold different types of books.

For example, let's say you're writing a program to store a list of names. With generics, you can create a "shelf" (or a data structure) that can hold any type of name – whether it's a string like "Alice" or "Bob," or even something more complex like "John Doe." This flexibility makes your code more reusable and adaptable to different situations.

Without generics, you'd have to create separate shelves for each type of data you want to store, which would be like having different shelves for novels, textbooks, and comics in the library. It would get messy and inefficient pretty quickly!

There are two types of generics

  • Generic class
  • Generic method

Generic class

java
// Example of a generic class
class Box<T> {
    private T content;

    public Box(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }
}

public class GenericsExample {
    public static void main(String[] args) {
        // Create a Box of Integer
        Box<Integer> integerBox = new Box<>(42);
        int intValue = integerBox.getContent(); // No need for casting!

        // Create a Box of String
        Box<String> stringBox = new Box<>("Hello, Generics!");
        String stringValue = stringBox.getContent(); // No casting needed here either!

        System.out.println("Integer value: " + intValue);
        System.out.println("String value: " + stringValue);
    }
}

In this example, we've defined a generic class called Box, which can hold any type of content. We create instances of Box for both Integer and String types, and we can retrieve the content without needing to cast it to the appropriate type. How convenient is that?

Generic Methods

java
// Example of a generic method
class Util {
    public static <T> T getLastElement(T[] array) {
        return array[array.length - 1];
    }
}

public class GenericsExample {
    public static void main(String[] args) {
        Integer[] intArray = {1, 2, 3, 4, 5};
        Integer lastInt = Util.getLastElement(intArray);

        String[] stringArray = {"apple", "banana", "cherry"};
        String lastString = Util.getLastElement(stringArray);

        System.out.println("Last integer: " + lastInt);
        System.out.println("Last string: " + lastString);
    }
}

In this example, we've defined a generic method called getLastElement, which works with arrays of any type. We can use this method to retrieve the last element of both an array of integers and an array of strings, without having to duplicate code or write separate methods for each type.

Muti-type Generics

java
public class Pair<T, U> {
    private T first;
    private U second;

    public Pair(T first, U second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public U getSecond() {
        return second;
    }

    public void setFirst(T first) {
        this.first = first;
    }

    public void setSecond(U second) {
        this.second = second;
    }
}

public class MultiTypeGenericsExample {
    public static void main(String[] args) {
        Pair<String, Integer> pair1 = new Pair<>("Java", 10);
        Pair<Double, String> pair2 = new Pair<>(3.14, "Pi");

        System.out.println("Pair 1: " + pair1.getFirst() + ", " + pair1.getSecond());
        System.out.println("Pair 2: " + pair2.getFirst() + ", " + pair2.getSecond());
    }
}

In our example, we've created a Pair class with two type parameters, T and U, representing the types of the first and second elements of the pair, respectively. This allows us to create pairs of different types, such as <String, Integer> or <Double, String>, and use them interchangeably.

Now, let's break down what's happening:

  • We've defined a Pair class with two type parameters, T and U, representing the types of the first and second elements of the pair.
  • In our MultiTypeGenericsExample, we create two pairs—one with a String and an Integer, and the other with a Double and a String.
  • We then print out the elements of each pair, demonstrating how multi-type generics allow us to work with different types of data in a flexible and concise manner.

Waytojava is designed to make learning easier. We simplify examples for better understanding. We regularly check tutorials, references, and examples to correct errors, but it's important to remember that humans can make mistakes.