Java Learner logo
← Back to Learn
Advanced

Advanced Concepts

Explore modern Java features that make your code more powerful and expressive.

Topics

Advanced Concepts

Generics

Generics allow you to write flexible, reusable code that works with different types while maintaining type safety.

Why Use Generics?

// Without generics - not type-safe
ArrayList list = new ArrayList();
list.add("Hello");
list.add(123);
String text = (String) list.get(1);  // Runtime error!

// With generics - type-safe
ArrayList<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
// names.add(123);  // Compile-time error - type safety!
String name = names.get(0);  // No casting needed

Generic Classes

// Generic class with type parameter T
public class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

// Usage
public class Main {
    public static void main(String[] args) {
        // Box for String
        Box<String> stringBox = new Box<>();
        stringBox.set("Hello");
        String text = stringBox.get();
        
        // Box for Integer
        Box<Integer> intBox = new Box<>();
        intBox.set(42);
        int number = intBox.get();
        
        // Box for custom objects
        Box<Person> personBox = new Box<>();
        personBox.set(new Person("Alice", 25));
    }
}

Generic Methods

public class GenericMethods {
    // Generic method
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
    
    // Generic method with return type
    public static <T> T getFirst(T[] array) {
        if (array.length > 0) {
            return array[0];
        }
        return null;
    }
    
    public static void main(String[] args) {
        Integer[] numbers = {1, 2, 3, 4, 5};
        String[] names = {"Alice", "Bob", "Charlie"};
        
        printArray(numbers);  // 1 2 3 4 5
        printArray(names);    // Alice Bob Charlie
        
        Integer first = getFirst(numbers);
        String firstName = getFirst(names);
    }
}

Bounded Type Parameters

// Upper bound: T must be Number or its subclass
public class Calculator<T extends Number> {
    private T value;
    
    public Calculator(T value) {
        this.value = value;
    }
    
    public double getDoubleValue() {
        return value.doubleValue();
    }
}

// Usage
Calculator<Integer> intCalc = new Calculator<>(42);
Calculator<Double> doubleCalc = new Calculator<>(3.14);
// Calculator<String> stringCalc = new Calculator<>("text");  // Error!