Generics in Java: Why They Are Needed and How to Use for Beginners
\n\nIf 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\nWhat are Generics in Java?
\n\nGenerics (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\nSimply 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\nThe Problem Without Generics
\n\nBefore the introduction of Generics (in Java 5), developers used type casting and worked with Object. This was inconvenient and dangerous:
// 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\nHere the compiler does not see the error, but the program will crash at runtime. Generics solve this problem.
\n\nWhy Are Generics Needed in Java?
\n\nGenerics 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
Example with Generics
\n\nSee 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\nThe code has become simpler, safer, and more readable.
\n\nHow to Use Generics: Basic Constructs
\n\nLet's look at three main ways to use generics: in classes, methods, and interfaces.
\n\n1. Generic Classes
\n\nYou 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):
// 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\n2. Generic Methods
\n\nYou 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\npublic 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\n3. Generic Interfaces
\n\nInterface