Lesson 40: Type Safety with Generics (<T>)
Generics were introduced in Java 5 to provide type safety at compile time. They allow a class or method to operate on objects of various types while retaining type checking capabilities.
1. The Problem Generics Solve
Before generics, collections stored objects as the base Object type. This meant the compiler couldn't verify the stored type, leading to potential ClassCastException errors at runtime.
java // Pre-Generics (Bad): List names = new ArrayList(); names.add("Alice"); names.add(10); // Compiler allows this, but it will cause a crash later
String name = (String) names.get(0); // String number = (String) names.get(1); // RUNTIME ERROR: ClassCastException
2. Using Generics
We specify the type inside angle brackets (<Type>) when declaring the collection. The type parameter is often represented by T (Type), E (Element), or K/V (Key/Value).
java
// With Generics (Good):
List
String name = names.get(0); // No casting required
3. Creating a Generic Class
You can make your own classes generic by adding a type parameter to the class declaration.
java
public class Box
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
// Usage:
Box
Key Concept (Erasure): Java generics are implemented using type erasure. At runtime, the type parameters are removed, and the compiler replaces them with Object or their upper bound. This ensures backward compatibility.