Generics em Java: para que servem e como usar para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Generics em Java: para que servem e como usar para iniciantes



Ao estudar Java, mais cedo ou mais tarde você encontrará o conceito de Generics (genéricos, generalizações). Para um iniciante, isso pode parecer complicado, mas na verdade é uma das ferramentas mais úteis da linguagem. Neste artigo, vamos entender o que são Generics, para que servem e como usá-los corretamente. O material é voltado para desenvolvedores iniciantes.



O que são Generics e por que é ruim sem eles?



Generics (generalizações) é um mecanismo do Java que permite parametrizar tipos. Em palavras simples, você pode escrever uma classe, interface ou método que funcionará com diferentes tipos de dados, mas mantendo a tipagem estrita em tempo de compilação.



Imagine que você quer criar uma caixa na qual possa colocar qualquer objeto. Sem Generics, você teria que usar Object:



public class Box {    private Object item;

public void put(Object item) { this.item = item; }

public Object get() { return item; }}


Usar essa classe é um verdadeiro tormento:



Box box = new Box();box.put("Hello");// Ao extrair, é necessário fazer uma conversão explícita de tipoString text = (String) box.get(); // Risco de ClassCastException!


Se você acidentalmente colocar um número e depois tentar convertê-lo para string — o programa falhará com um erro em tempo de execução. Generics resolvem esse problema, transferindo a verificação de tipos para o tempo de compilação.



Como usar Generics: sintaxe básica



Vamos reescrever nossa classe Box usando Generics:



public class Box<T> {    private T item;

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

public T get() { return item; }}


Aqui, <T> é o parâmetro de tipo. T é um nome convencional (da palavra "Type"), mas você pode usar qualquer letra ou palavra: E (Element), K (Key), V (Value), etc.



Agora o uso se tornou seguro e elegante:



Box<String> stringBox = new Box<>();stringBox.put("Hello");String text = stringBox.get(); // Sem necessidade de conversão!

// Esta linha não será compilada:// stringBox.put(123); // Erro de compilação!


O compilador sabe que stringBox funciona apenas com strings. Se você tentar colocar um número, o código nem será compilado — você saberá do erro imediatamente, e não em tempo de execução.



Generics em coleções: onde são mais necessários



O local mais comum de uso de Generics são as coleções do Java (List, Set, Map e outras). Antes do surgimento dos genéricos (no Java 5), os desenvolvedores sofriam com ArrayList, que armazenava Object:



// Estilo antigo (sem Generics)List list = new ArrayList();list.add("Olá");list.add(123); // Isso também pode ser adicionado!

String item = (String) list.get(0); // NormalString item2 = (String) list.get(1); // ClassCastException!


Com Generics, tudo é mais simples e seguro:



List<String> names = new ArrayList<>();names.add("Alice");names.add("Bob");// names.add(123); // Erro de compilação

for (String name : names) { System.out.println(name.toUpperCase()); // Sem conversões!}


O mesmo funciona para Map:



Map<String, Integer> ageMap = new HashMap<>();ageMap.put("Alice", 30);ageMap.put("Bob", 25);

int aliceAge = ageMap.get("Alice"); // Desempacotamento automático int


Restrições e wildcards: como tornar Generics flexíveis



Às vezes, você precisa restringir quais tipos um genérico pode aceitar. Para isso, são usados bounded type parameters (parâmetros de tipo limitados).



Exemplo

Blogs

Book Recommendations