</>

Technology

Core Java

Difficulty

Intermediate

Interview Question

What is Java Generics? Why are they used?

Answer

Java Generics

Generics allow you to write type-safe code that works with different data types while providing compile-time type checking.

Why Generics?

Java
// WITHOUT generics — unsafe, requires casting
List list = new ArrayList();
list.add("Hello");
list.add(42);        // no type check!

String s = (String) list.get(1);  // ClassCastException at runtime!

// WITH generics — type-safe
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
// stringList.add(42);  // ❌ Compile error — caught at compile time!
String s = stringList.get(0);  // no cast needed

Generic Class

Java
public class Box<T> {
    private T content;

    public void put(T item) { this.content = item; }
    public T get()          { return content; }
}

Box<String> stringBox = new Box<>();
stringBox.put("Hello");
String s = stringBox.get();   // no cast

Box<Integer> intBox = new Box<>();
intBox.put(42);
Integer n = intBox.get();

Generic Method

Java
public class ArrayUtils {
    // Works with ANY type
    public static <T> void swap(T[] arr, int i, int j) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static <T extends Comparable<T>> T max(T a, T b) {
        return a.compareTo(b) > 0 ? a : b;
    }
}

Integer[] nums = {1, 2, 3};
ArrayUtils.swap(nums, 0, 2); // [3, 2, 1]

System.out.println(ArrayUtils.max(10, 20));       // 20
System.out.println(ArrayUtils.max("Apple", "Banana")); // Banana

Bounded Type Parameters

Java
// <T extends Number> — T must be Number or subclass (Integer, Double, Float)
public static <T extends Number> double sum(List<T> list) {
    return list.stream().mapToDouble(Number::doubleValue).sum();
}

List<Integer> ints    = Arrays.asList(1, 2, 3);
List<Double> doubles  = Arrays.asList(1.5, 2.5, 3.5);
System.out.println(sum(ints));    // 6.0
System.out.println(sum(doubles)); // 7.5

Wildcards

Java
// ? — unknown type
// ? extends T — upper bound (T or subclass)
// ? super T — lower bound (T or superclass)

// Read-only — accepts List<Integer>, List<Double>, List<Number>
public static double sumList(List<? extends Number> list) {
    return list.stream().mapToDouble(Number::doubleValue).sum();
}

// Write — accepts List<Integer> or List<Number> or List<Object>
public static void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
}

Common Generic Collections

Java
// All Collections use generics
List<String>              names  = new ArrayList<>();
Map<String, Integer>      scores = new HashMap<>();
Set<Long>                 ids    = new HashSet<>();
Queue<Runnable>           tasks  = new LinkedList<>();
Optional<WebDriver>       driver = Optional.empty();

In Automation Frameworks

Java
// Generic utility to wait for any element type
public static <T extends WebElement> T waitForElement(
        WebDriverWait wait, ExpectedCondition<T> condition) {
    return wait.until(condition);
}

// Generic page factory method
public static <T extends BasePage> T initPage(WebDriver driver, Class<T> pageClass) {
    try {
        return pageClass.getConstructor(WebDriver.class).newInstance(driver);
    } catch (Exception e) {
        throw new RuntimeException("Failed to init page: " + pageClass.getName(), e);
    }
}

// Usage
LoginPage loginPage = initPage(driver, LoginPage.class);

Follow AutomateQA

Related Topics