Um conceito bem interessante que muitos devs podem não estar tão familiarizados ao trabalhar com Generics é o Type Erasure. Os tipos genéricos que definimos no código são removidos pelo compilador, resultando em tipos mais básicos em tempo de execução, como Object.
Isso garante compatibilidade com versões mais antigas do Java, mas limita o uso de certos tipos e operações, como verificar o tipo genérico com instanceof.
Entender um pouco sobre Type Erasure ajuda a pensar em soluções requintadas.
O que são Generecis ?
Generics permitem que você crie classes, interfaces e métodos que funcionam com tipos especificos de maneira flexível.
Você pode reutilizar o código com diferentes tipos sem comprometer a segurança em tempo de compilação.
Exemplo:
Podemos criar uma Equipe de Surf que aceita qualquer tipo de modalidade, seja de pranchinha ou pranchão, usando Generics.
class EquipeSurf<T> {
private T surfista;
public void adicionar (T surfista) {
this.surfista= surfista;
}
public T getSurfista (){
return surfista;
}
}
Como usar Generics para restringir tipo?
Você pode limitar o tipo de parametro usando extends ou super para restringir a hierarquia de tipos aceitos.
Exemplo:
Podemos garantir que apenas surfistas que sejam subclasses de Atletas possam ser membros da equipe de surf
class EquipeSurfe <T extends Atleta> {
//implementação
}
O que são wildcards (?) em Generics ?
Eles representam um tipo desconhecido. São úteis quando você quer trabalhar com uam coleção sem saber o tipo exato de seus elementos.
Exemplo:
Imagine que você tem uma lista de diferentes tipos de Atletas e quer checar se o surfista está em alguma dessas listas.
public static void checarSurfista(List<?> lista, Objetc surfista){
if (lista.contains(surfista)){
System.out.println ("Surfista está na lista!")
}else{
System.out.println ("Surfista não está na lista.")}
}
Como funcionam métodos genéricos?
Um método genérico define um parâmetro de tipo independente do tipo da classe. Isso permite que métodos funcionem com vários tipos, sem perder a segurança de tipos.
Exemplo:
Podemos criar um método que aceita qualquer tipo de Categoria de Surfista e a exibe:
public static <T> void mostrarCategoria(T categoria){
System.out.println(categoria.toString());
}
O que é Type Erasure?
Type Erasure é o processo pelo qual as informações de tipos genéricos são removidas pelo compilador. Isso garante compatibilidade com versões anteriores do java.
Exemplo:
Mesmo que adicionemos categorias como iniciante ou kahuna a uma lista genérica, em tempo de execução, o tipo exato não será mais conhecido, pois foi “apagado”.
Como os Generics funcionam com Interfaces Funcionais, como Predicate?
Generics podem ser usados com interfaces funcionais para criar comportamentos dinâmicos baseados em condções específicas.
Exemplo:
Podemos criar uma função que filtra atletas que foram “Campeões” em uma lista de Títulos:
Predicate<Surfista> ehcampeao = surfista -> surfista.getTitulos().contains("Campeão");
surfistas.stream().filter(ehcampeao).forEach(System.out::println);
0 comentário