Java Generics

Java Generics
Generics in Java provide type safety and code reusability by allowing classes, interfaces, and methods to operate on parameterized types. This means you can create classes and methods that work with different data types without losing type safety.
1. Why Use Generics?
Without Generics (Using Object)
Before generics, Java used the Object class to store different types. However, this required explicit type casting, which could lead to runtime errors.
✅ Example (Without Generics)
import java.util.ArrayList;
public class WithoutGenerics {
public static void main(String[] args) {
ArrayList list = new ArrayList(); // No type safety
list.add("Hello");
list.add(100); // No error at compile time
String str = (String) list.get(0); // Type casting required
System.out.println(str);
// This will cause a runtime error
// String num = (String) list.get(1); // ClassCastException
}
}
🚨 Problems with the above approach:
No Type Safety – Different types can be added to the list.
Explicit Type Casting – Risk of ClassCastException.
2. Generics in Java
With generics, we can define a parameterized type that ensures compile-time type safety.
✅ Example (With Generics)
import java.util.ArrayList;
public class WithGenerics {
public static void main(String[] args) {
ArrayListlist = new ArrayList<>(); // Type-safe
list.add("Hello");
// list.add(100); // Compile-time error
String str = list.get(0); // No type casting needed
System.out.println(str);
}
}
class Utility {
// Generic method with
public staticvoid printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
}
public class GenericMethodExample {
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4, 5};
String[] strArray = {"Hello", "World"};
Utility.printArray(intArray);
Utility.printArray(strArray);
}
}
class MathOperations{ // T must be a subclass of Number
private T number;
public MathOperations(T number) {
this.number = number;
}
public double square() {
return number.doubleValue() * number.doubleValue();
}
}
public class BoundedGenericsExample {
public static void main(String[] args) {
MathOperationsintOp = new MathOperations<>(5);
System.out.println("Square of 5: " + intOp.square());
MathOperationsdoubleOp = new MathOperations<>(5.5);
System.out.println("Square of 5.5: " + doubleOp.square());
// MathOperationsstrOp = new MathOperations<>("Hello"); // Compile-time error
}
}
import java.util.List;
import java.util.Arrays;
public class WildcardExample {
public static void printList(List> list) { // Accepts any type
for (Object obj : list) {
System.out.print(obj + " ");
}
System.out.println();
}
public static void main(String[] args) {
ListintList = Arrays.asList(1, 2, 3);
ListstrList = Arrays.asList("A", "B", "C");
printList(intList);
printList(strList);
}
}
import java.util.Arrays;
import java.util.List;
public class BoundedWildcardExample {
public static double sum(List extends Number> numbers) {
double sum = 0.0;
for (Number num : numbers) {
sum += num.doubleValue();
}
return sum;
}
public static void main(String[] args) {
ListintList = Arrays.asList(1, 2, 3);
ListdoubleList = Arrays.asList(1.5, 2.5, 3.5);
System.out.println("Sum of Integers: " + sum(intList));
System.out.println("Sum of Doubles: " + sum(doubleList));
}
}
Date: 2025-03-28 00:00:00.000000