Home

 › 

Articles

 › 

Understanding Java Generics, With Examples

php vs. java

Understanding Java Generics, With Examples

Key Points

  • Java generics are a powerful tool that can make code more readable and reusable.
  • Generics enable the creation of classes, interfaces, and methods that can operate on different data types while ensuring type safety.
  • Using Java generics can improve code readability and performance, and they can be used for interfaces as well.
  • Generics become increasingly important when creating larger projects in Java.

Java Generics is a powerful tool that can make your code much more readable and reusable. Its main function is to enable the creation of classes, interfaces, and methods that can operate on different data types while ensuring type safety.

In this today’s guide, we will go over what generics are and how they can be used to their fullest extent. Let’s jump in!

What Are Generics?

General Class Without Generics

If you wanted a class to work on multiple data types, you would normally have to make it operate on Object. Here’s what that might look like for a Stack class:

public class Stack {
    private Object[] elements;
    private int top;

    public Stack(int capacity) {
        elements = new Object[capacity];
        top = -1;
    }

    public void push(Object item) {
        if (top == elements.length - 1) {
            throw new RuntimeException("Stack is full");
        }
        elements[++top] = item;
    }

    public Object pop() {
        if (top == -1) {
            throw new RuntimeException("Stack is empty");
        }
        return elements[top--];
    }

    public boolean isEmpty() {
        return top == -1;
    }
}

If we want to create a stack and put a number on it, we can simply do the following:

Stack stack = new Stack(5);
stack.push(10);

However, if we want to pop off a number and use it as an integer later, since it is technically an Object, we must cast it.

Object uncastedNumber = stack.pop();
int castedNumber = (int) uncastedNumber;

And then we can use it.

General Class with Generics

With Java Generics, this is unnecessary. Here’s how we can write the same class using it:

public class Stack<T> {
    private T[] elements;
    private int top;

    @SuppressWarnings("unchecked")
    public Stack(int capacity) {
        elements = (T[]) new Object[capacity];
        top = -1;
    }

    public void push(T item) {
        if (top == elements.length - 1) {
            throw new RuntimeException("Stack is full");
        }
        elements[++top] = item;
    }

    public T pop() {
        if (top == -1) {
            throw new RuntimeException("Stack is empty");
        }
        return elements[top--];
    }

    public boolean isEmpty() {
        return top == -1;
    }
}

Note that the @SuppressWarnings(“unchecked”) annotation is only there to keep Java from giving you the “unchecked cast” warning.

The use of angle brackets (<>) is a giveaway that generics are being used. As can be seen, <T> is placed after the class name, indicating that any class can be put there to tell Java what type of data is being operated on.

Then, anywhere in the function, the token T can be used to refer to the chosen class. Here’s can the generic class can now be used:

Stack<Integer> stack = new Stack<>(5);
stack.push(10);
int number = stack.pop();

Unlike the last example, casting is not necessary. It should be noted that the class that is put in angle brackets cannot be a primitive data type. Here, Integer is used instead of int, although they are often functionally equivalent.

Wrapping Up: Java Generics

Although you may not have realized it up until now, you have likely used generics before. They are often used with common classes like ArrayList, LinkedList, and HashMap. When these are used with generics, they are much more powerful, as they can easily be used on a wide variety of data.

Using Java generics will help you improve your code readability and performance. Although only a class example was shown, they can also be used for interfaces

When creating larger projects in Java, generics become increasingly important, as your code becomes more flexible and adaptable. There is much more to learn, and we encourage you to learn everything you can about generics to become a more proficient developer!

Summary Table

TopicDescription
What are Generics?Generics enable the creation of classes, interfaces, and methods that can operate on different data types while ensuring type safety.
General Class Without GenericsIf you wanted a class to work on multiple data types, you would normally have to make it operate on Object. However, if we want to use it as an integer later, since it is technically an Object, we must cast it.
General Class With GenericsWith Java generics, casting is unnecessary. The use of angle brackets (<>) is a giveaway that generics are being used. The class that is put in angle brackets cannot be a primitive data type.
Wrapping Up: Java GenericsUsing Java generics will help you improve your code readability and performance. They are often used with common classes like ArrayList, LinkedList, and HashMap. When creating larger projects in Java, generics become increasingly important, as your code becomes more flexible and adaptable.

Frequently Asked Questions

What are generics used for in Java?

Generics are used in classes, interfaces, and methods to make them reusable between different data types. By doing this, they become much more versatile and “generic”, hence the name. They are applied in commonly used classes like ArrayList and HashMap.

How to make a generic in Java?

A generic class or interface can be created by writing <T> after their name. Then, the token T can be used anywhere to reference the class chosen for that situation.

What does T mean in Java?

<T> is used to create a generic class or interface. It goes after the class or interface name, and afterward, T can be used as a placeholder for the chosen class.

When should you use generics?

You should use generics anytime you will use a class or interface in situations that operate on different data types. When you do this, type safety is ensured, and it becomes much easier to work with them in different contexts.

To top