DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

Item 32: Seja criterioso ao combinar os genéricos com os varargs

Introdução:
Métodos varargs e genéricos foram introduzidos no Java 5.
Interação entre eles nem sempre é pacífica devido a vazamentos de abstração.

  1. Problemas com varargs e genéricos: Criação de arrays para parâmetros varargs torna-se visível, resultando em advertências do compilador. Tipos não reificados (parametrizados ou genéricos) causam advertências na declaração e invocação de métodos varargs.

Image description

  1. Poluição do heap: Ocorre quando uma variável de tipo parametrizado referencia um objeto de outro tipo, podendo causar falhas de ClassCastException.

Exemplo de problema:
Um método aparentemente seguro pode falhar com ClassCastException devido a casts invisíveis gerados pelo compilador.

Image description

  1. Inconsistências permitidas: Métodos com parâmetros varargs genéricos são permitidos, apesar das inconsistências, devido à sua utilidade prática. Exemplos de métodos seguros incluem Arrays.asList, Collections.addAll, e EnumSet.of.

Image description

  1. Introdução do @SafeVarargs: Introduzido no Java 7 para suprimir automaticamente advertências de métodos varargs genéricos que são seguros. Representa uma promessa do autor do método de que ele é seguro.

Image description

  1. Garantia de segurança: Não armazene nada no array de parâmetros varargs. Não permita que referências ao array escapem para código não confiável.

Exemplo de método perigoso:
Métodos que retornam um array de parâmetros varargs podem propagar poluição do heap.

Uso seguro de varargs:
Passar arrays varargs para métodos adequadamente anotados ou que apenas calculam funções do conteúdo do array.

Exemplo de uso seguro:
Método que aceita várias listas e retorna uma lista contendo todos os elementos.

Image description

  1. Regras para @SafeVarargs:
    Use em métodos com parâmetros varargs genéricos para evitar advertências desnecessárias.
    Métodos anotados devem ser estáticos ou finais (Java 8), ou privados (Java 9).

  2. Alternativa com List:
    Substituir varargs por List para provar que o método é seguro.
    Pode resultar em código cliente mais verboso e ligeiramente mais lento.

Image description

Conclusão:
Varargs e genéricos não interagem bem devido a vazamentos de abstração e diferenças nas regras de tipagem.
Garanta que métodos com parâmetros varargs genéricos sejam seguros e anote-os com @SafeVarargs.

Este resumo captura os pontos principais do artigo, destacando os problemas, soluções e boas práticas ao combinar varargs com genéricos no Java.

Top comments (0)