Generics
Tipos parametrizados e type safety
Generics permitem criar classes, interfaces e métodos que funcionam com tipos definidos pelo usuário, usando parâmetros de tipo representados por letras como T, E, K, V. Em vez de trabalhar com Object e fazer casts arriscados, você usa Box<String> ou Box<Integer> — o compilador garante a segurança dos tipos.
Os benefícios são: type safety em tempo de compilação (ClassCastException viram erros de compilação), eliminação de casts desnecessários, e reutilização de código. As Collections do Java (List<T>, Map<K,V>, Set<E>) são todas genéricas — a mesma implementação funciona para qualquer tipo.
Bounded wildcards limitam os tipos aceitos: <T extends Number> aceita Number e suas subclasses (Integer, Double…). Wildcards com ? são usados quando o tipo específico não importa: List<?> aceita qualquer tipo de lista.
// ── Classe genérica ───────────────────────────────
public class Par<A, B> {
private final A primeiro;
private final B segundo;
public Par(A primeiro, B segundo) {
this.primeiro = primeiro;
this.segundo = segundo;
}
public A getPrimeiro() { return primeiro; }
public B getSegundo() { return segundo; }
@Override
public String toString() {
return "(" + primeiro + ", " + segundo + ")";
}
}
// ── Método genérico ───────────────────────────────
public static <T extends Comparable<T>> T maximo(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
// ── Uso ──────────────────────────────────────────
Par<String, Integer> linguagem = new Par<>("Java", 1995);
Par<Double, Boolean> dado = new Par<>(3.14, true);
System.out.println(linguagem); // (Java, 1995)
System.out.println(dado); // (3.14, true)
System.out.println(maximo(10, 25)); // 25
System.out.println(maximo("Ana", "Carlos")); // Carlos (alfabético)
// ── Bounded wildcard ─────────────────────────────
public static double somarLista(List<? extends Number> lista) {
return lista.stream().mapToDouble(Number::doubleValue).sum();
}Generics são apagados em runtime (type erasure) — em tempo de execução, List<String> e List<Integer> são ambas apenas List. Isso limita reflection e instanceof com tipos parametrizados.