Os generics em Java são implementados com a técnica de "type erasure", o que significa que os tipos genéricos são substituídos por Object no tempo de execução. Isso pode causar problemas ao deserializar objetos JSON, onde é necessário usar TypeReference para resolver a ambiguidade dos tipos genéricos.
Classe Genérica
public class Resultado<T> {
private int codigo;
private String mensagem;
private T dado;
}
Métodos Genéricos
Aqui estão exemplos de métodos genéricos. Note que os últimos dois métodos são equivalentes, mas o último tem melhor legibilidade e não requer cast do tipo de retorno.
public static Object getPrimeiroElemento(List list) {
return list.get(0);
}
public static Object getPrimeiroElemento(List<Object> list) {
return list.get(0);
}
public static Object getPrimeiroElemento(List<?> list) {
return list.get(0);
}
public static <T> T getPrimeiroElemento(List<T> list) {
return list.get(0);
}
Deserialização Genérica
Para deserializar um objeto genérico, você pode passar a classe diretamente se houver apenas um nível de genérico. Para casos mais complexos, use TypeReference.
public static <T> T lerArquivoParaObjeto(File arquivo, Class<T> clazz) {
T objeto;
try {
objeto = clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Erro na construção do objeto via reflexão");
}
return objeto;
}
List<Aluno> lista = JSON.parseObject("""
[{"nome":"João","idade":18},{"nome":"Maria","idade":19}]
""",
new TypeReference<List<Aluno>>() {});
Iteradores
Com a introdução da API Stream no JDK 8, o uso de iteradores diminuiu significativamente. A partir do JDK 17, as otimizações na API Stream tornaram o uso de iteradores ainda menos comum. Para conjuntos de dados menores, o uso de iteradores é aceitável, mas para grandes volumes de dados, o loop for ou streams paralelas são mais eficientes.
Interface Iterable
A interface Iterable permite que uma coleção seja percorrida usando o loop for-each, que é essencialmente uma sintaxe açucarada para o uso de iteradores.
Clonagem
A clonagem em Java, introduzida no JDK 1.0, tem algumas falhas de design, especialmente quando lidando com herança ou tipos de dados complexos. Embora não esteja obsoleta, é recomendado criar novos objetos e copiar os valores necessários.
Diferença entre Clonagem Rasa e Profunda
A clonagem rasa cria uma cópia superficial, onde os atributos de tipos complexos referenciam os mesmos objetos. A clonagem profunda, por outro hand, cria novas instâncias desses objetos, resultando em referências independentes.