O conceito de generics permite criar classes, interfaces e métodos que funcionam com diferentes tipos de dados, mantendo segurança em tempo de compilação, eliminando casts desnecessários e promovendo reutilização de código.


🧰 Uma Analogia Simples: A Bolsa de Equipamentos

Imagine uma Bolsa de Equipamentos usada por um guerreiro experiente.

Essa bolsa deve ser capaz de armazenar qualquer ferramenta — mas sempre garantindo que, ao retirar o item, você receba exatamente o tipo esperado.

Essa é a essência dos generics: flexibilidade sem perder segurança.


🔑 Conceitos Fundamentais


📦 1. Exemplo Básico — Uma Bolsa Genérica de Ferramentas

// Classe genérica capaz de armazenar qualquer tipo de ferramenta
public class Bolsa<T> {
    private T item;

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

    public T pegar() {
        return item;
    }

    public static void main(String[] args) {
        Bolsa<Kunai> bolsaKunai = new Bolsa<>();
        bolsaKunai.adicionar(new Kunai("Kunai de Combate"));
        System.out.println("Ferramenta: " + bolsaKunai.pegar().getNome());

        Bolsa<Shuriken> bolsaShuriken = new Bolsa<>();
        bolsaShuriken.adicionar(new Shuriken("Shuriken Estrela"));
        System.out.println("Ferramenta: " + bolsaShuriken.pegar().getNome());
    }
}

class Kunai {
    private String nome;
    public Kunai(String nome) { this.nome = nome; }
    public String getNome() { return nome; }
}

class Shuriken {
    private String nome;
    public Shuriken(String nome) { this.nome = nome; }
    public String getNome() { return nome; }
}


🧳 2. Exemplo Avançado — Bolsa com Lista de Equipamentos

import java.util.ArrayList;
import java.util.List;

public class BolsaGenerica<T> {
    private List<T> equipamentos;

    public BolsaGenerica() {
        this.equipamentos = new ArrayList<>();
    }

    public void adicionar(T equipamento) {
        equipamentos.add(equipamento);
    }

    public List<T> getEquipamentos() {
        return equipamentos;
    }

    @Override
    public String toString() {
        return "Equipamentos: " + equipamentos;
    }
}

class Equipamento {
    private String nome;

    public Equipamento(String nome) {
        this.nome = nome;
    }

    @Override
    public String toString() {
        return nome;
    }
}

// Teste
public class Main {
    public static void main(String[] args) {
        Equipamento kunai = new Equipamento("Kunai de Ferro");
        Equipamento shuriken = new Equipamento("Shuriken");
        Equipamento pergaminho = new Equipamento("Pergaminho Secreto");

        BolsaGenerica<Equipamento> bolsa = new BolsaGenerica<>();
        bolsa.adicionar(kunai);
        bolsa.adicionar(shuriken);
        bolsa.adicionar(pergaminho);

        System.out.println(bolsa);
    }
}