Java Generics – Complete Detailed Notes
1. Introduction to Generics
Generics in Java allow classes, interfaces, and methods to operate on different data types while
providing type safety. They were introduced to eliminate runtime errors caused by incorrect type
casting.
Problem Without Generics
ArrayList list = new ArrayList();
[Link]("Hello");
[Link](10);
String s = (String) [Link](1); // Runtime Error
Solution Using Generics
ArrayList<String> list = new ArrayList<>();
[Link]("Hello");
// [Link](10); // Compile-time error
2. Generic Classes
A generic class allows you to define a class with a type parameter.
class Box<T> {
T value;
void set(T value) {
[Link] = value;
}
T get() {
return value;
}
}
3. Generic Methods
A generic method can work with different types independently of the class.
class Test {
static <T> void print(T data) {
[Link](data);
}
}
4. Bounded Generics
Bounded generics restrict the type parameter to a specific range.
class Test<T extends Number> {
T value;
}
5. Wildcards
Wildcards (?) represent unknown types.
List<?> list;
List<? extends Number> list1;
List<? super Integer> list2;
6. Type Erasure
Generics are removed at runtime. This process is called type erasure.
List<Integer> list = new ArrayList<>();
// At runtime becomes:
List list = new ArrayList();
7. Generics with Collections
Generics are widely used with collections for type safety.
ArrayList<String> list = new ArrayList<>();
HashMap<Integer, String> map = new HashMap<>();
8. Advantages of Generics
- Type Safety - No need for casting - Code reusability - Compile-time checking
9. Limitations
- Cannot use primitive types - No runtime type information - Cannot create generic exceptions
10. PECS Rule
PECS stands for Producer Extends, Consumer Super. It helps decide wildcard usage.
List<? extends Number> // Read only
List<? super Integer> // Write allowed