Dominando Java Generics – Construindo Código Reutilizável e Type-Safe
Java Generics – Construindo Código Reutilizável e Type-Safe
Este guia explica Java generics, como criar classes e métodos genéricos, e os benefícios que trazem, ilustrados com exemplos claros.
Java generics permitem escrever uma classe, interface ou método que pode operar em muitos tipos de dados diferentes, mantendo segurança em tempo de compilação.
Nota: Generics não funcionam com tipos primitivos (int, float, char, etc).
Classe Generics em Java
Declarando um parâmetro de tipo, você pode criar uma classe que funciona com qualquer tipo de objeto.
Exemplo: Criar uma Classe Genérica
class Main {
public static void main(String[] args) {
GenericsClass<Integer> intObj = new GenericsClass<>(5);
System.out.println("Classe Genérica retorna: " + intObj.getData());
GenericsClass<String> stringObj = new GenericsClass<>("Programação Java");
System.out.println("Classe Genérica retorna: " + stringObj.getData());
}
}
class GenericsClass<T> {
private T data;
public GenericsClass(T data) {
this.data = data;
}
public T getData() {
return this.data;
}
}
Saída
Classe Genérica retorna: 5 Classe Genérica retorna: Programação Java
No exemplo acima, GenericsClass é uma classe genérica onde T é o parâmetro de tipo. Duas instâncias são criadas:
- intObj – T é substituído por
Integer, então a classe trabalha com inteiros. - stringObj – T é substituído por
String, então a classe trabalha com strings.
Método Generics em Java
Métodos também podem ser genéricos, permitindo que aceitem qualquer tipo de argumento mantendo type safety.
Exemplo: Criar um Método Genérico
class Main {
public static void main(String[] args) {
DemoClass demo = new DemoClass();
demo.<String>genericsMethod("Programação Java");
demo.<Integer>genericsMethod(25);
}
}
class DemoClass {
public <T> void genericsMethod(T data) {
System.out.println("Método Genérico:");
System.out.println("Dado Passado: " + data);
}
}
Saída
Método Genérico: Dado Passado: Programação Java Método Genérico: Dado Passado: 25
Quando o compilador pode inferir o tipo, você pode omitir o argumento de tipo explícito:
demo.genericsMethod("Programação Java");
Tipos Limitados (Bounded Types)
Às vezes você quer que um tipo genérico aceite apenas uma família específica de classes. Tipos limitados alcançam isso usando a palavra-chave extends.
Sintaxe: <T extends A> – T pode ser A ou qualquer subtipo de A.
Exemplo: Tipos Limitados
class GenericsClass <T extends Number> {
public void display() {
System.out.println("Esta é uma classe genérica de tipo limitado.");
}
}
class Main {
public static void main(String[] args) {
// GenericsClass<String> obj = new GenericsClass<>(); // erro de compilação
}
}
Aqui, GenericsClass aceita apenas tipos numéricos (Integer, Double, etc.). Tentar instanciá-lo com String causa erro de compilação:
GenericsClass<String> obj = new GenericsClass<>(); ^ reason: inference variable T has incompatible bounds equality constraints: String lower bounds: Number where T is a type-variable: T extends Number declared in class GenericsClass
Vantagens de Java Generics
1. Reutilização de Código
Código genérico pode operar em múltiplos tipos de dados, reduzindo duplicação. Por exemplo, um único método pode processar inteiros, strings e objetos personalizados.
2. Verificação de Tipo em Tempo de Compilação
Como o parâmetro de tipo é conhecido em tempo de compilação, o compilador pode detectar mismatches de tipo antes da execução do programa.
3. Integração Perfeita com Collections
O framework de coleções do Java é baseado em generics, permitindo que coleções imponham type safety. Exemplos:
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
Outras classes de coleção (LinkedList, Queue, Map, etc.) também usam generics pelos mesmos benefícios.
Java
- Entendendo a Palavra-chave final em Java: Variáveis, Métodos e Classes
- Operador instanceof em Java: Guia Completo
- Dominando Herança em Java: Conceitos, Tipos e Exemplos Práticos
- Entendendo Classes Aninhadas Estáticas em Java: Uso, Diferenças e Exemplos
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Padrão Singleton em Java Explicado: Como Implementar e Usar com Segurança
- Dominando Reflection em Java: Inspecionando Classes, Métodos e Campos em Tempo de Execução
- Dominando ArrayList em Java: Operações, Métodos e Boas Práticas
- Dominando Java ObjectOutputStream: Serialização, Métodos e Exemplos Práticos
- Dominando Operações de Arquivo em Java com java.io – Criação, Leitura, Escrita e Exclusão