Generics Fundamentals
Introduction to Generics in Java
Generics in Java provide a powerful way to create type-safe and reusable code. They allow developers to write flexible and robust algorithms that can work with different types while maintaining compile-time type checking.
Basic Concepts of Generics
Type Parameters
Generics introduce type parameters, which enable creating classes, interfaces, and methods that can work with different types:
public class GenericBox<T> {
private T content;
public void set(T value) {
this.content = value;
}
public T get() {
return content;
}
}
Generic Methods
Generic methods allow type parameters to be used independently of the class:
public <E> void printArray(E[] array) {
for (E element : array) {
System.out.print(element + " ");
}
}
Generics Type Bounds
Upper Bounded Wildcards
Restrict type parameters to specific hierarchies:
public void processList(List<? extends Number> numbers) {
// Process only lists of Number or its subclasses
}
Lower Bounded Wildcards
Allow processing of lists with specific base types:
public void addNumbers(List<? super Integer> list) {
list.add(10);
list.add(20);
}
Generics Limitations
Type Erasure
Java implements generics through type erasure, which means generic type information is removed at runtime:
graph TD
A[Compile-Time] --> B[Generic Type with Type Parameter]
B --> C[Runtime Type Erasure]
C --> D[Raw Type]
Restrictions
Key limitations of generics include:
Limitation |
Description |
Example |
No Primitive Types |
Cannot use primitive types directly |
Cannot use List<int> |
No Instantiation |
Cannot create instances of type parameters |
Cannot do new T() |
No Static Members |
Cannot have static members with type parameters |
Cannot declare static fields with type T |
Best Practices
- Use meaningful type parameter names
- Prefer composition over inheritance with generics
- Understand type erasure implications
- Use wildcards judiciously
Practical Example
public class GenericUtility {
public static <T extends Comparable<T>> T findMax(T a, T b) {
return (a.compareTo(b) > 0) ? a : b;
}
public static void main(String[] args) {
Integer maxInteger = findMax(5, 10);
String maxString = findMax("Hello", "World");
System.out.println("Max Integer: " + maxInteger);
System.out.println("Max String: " + maxString);
}
}
By mastering these generics fundamentals, developers can write more flexible and type-safe code using LabEx's recommended practices.