Generics in Java: Why They Are Needed and How to Use for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Generics in Java: Why They Are Needed and How to Use for Beginners

\n\n

If you are just starting to learn Java, sooner or later you will encounter the concept of Generics (generic types). This powerful language feature allows you to write more flexible, safe, and reusable code. In this article, we will explain in simple terms what Generics are, why they are needed, and how to apply them in practice.

\n\n

What are Generics in Java?

\n\n

Generics (from "generic" — general, generic) is a Java mechanism that allows you to create classes, interfaces, and methods that work with different data types while ensuring strict type checking at compile time.

\n\n

Simply put, generics allow you to specify: "This class or method will work with any data type, but I don't know which one yet." The type is determined later when you create an object or call a method.

\n\n

The Problem Without Generics

\n\n

Before the introduction of Generics (in Java 5), developers used type casting and worked with Object. This was inconvenient and dangerous:

\n\n
// Without Generics (old style)\nList list = new ArrayList();\nlist.add("Hello");\nlist.add(123); // Error? No, the compiler will allow it\n\nString text = (String) list.get(0); // Casting is mandatory\n// String num = (String) list.get(1); // ClassCastException at runtime!
\n\n

Here the compiler does not see the error, but the program will crash at runtime. Generics solve this problem.

\n\n

Why Are Generics Needed in Java?

\n\n

Generics bring three key advantages:

\n\n
    \n
  • Type Safety — errors are detected at compile time, not at runtime.
  • \n
  • No Casting — you don't need to write (String) every time.
  • \n
  • Code Reuse — one class or method can work with different types.
  • \n
\n\n

Example with Generics

\n\n

See how the code changes when using generics:

\n\n
// With Generics\nList<String> list = new ArrayList<>();\nlist.add("Hello");\n// list.add(123); // Compilation error! Cannot add Integer\n\nString text = list.get(0); // No casting needed\n// The compiler already knows it's a String
\n\n

The code has become simpler, safer, and more readable.

\n\n

How to Use Generics: Basic Constructs

\n\n

Let's look at three main ways to use generics: in classes, methods, and interfaces.

\n\n

1. Generic Classes

\n\n

You can create a class that works with any type. To do this, after the class name in angle brackets, specify a type parameter (usually T, E, K, V):

\n\n
// Generic class "Box"\npublic class Box<T> {\n    private T content;\n\n    public void put(T item) {\n        this.content = item;\n    }\n\n    public T get() {\n        return content;\n    }\n}\n\n// Usage\nBox<String> stringBox = new Box<>();\nstringBox.put("Book");\nString book = stringBox.get(); // No casting\n\nBox<Integer> intBox = new Box<>();\nintBox.put(42);\nint number = intBox.get();
\n\n

2. Generic Methods

\n\n

You can make not the entire class generic, but only a specific method. This is useful when a method should handle different types independently of the class:

\n\n
public class Utils {\n    // Generic method\n    public static <T> void printArray(T[] array) {\n        for (T element : array) {\n            System.out.print(element + " ");\n        }\n        System.out.println();\n    }\n}\n\n// Call\nInteger[] intArray = {1, 2, 3};\nString[] strArray = {"A", "B", "C"};\n\nUtils.printArray(intArray); // 1 2 3\nUtils.printArray(strArray); // A B C
\n\n

3. Generic Interfaces

\n\n

Interface

Blogs

Book Recommendations