← 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 neededGeneric 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!