List super Animal>
(limite inferior) pode adicionarAnimal
e seus subtipos.
List extends Animal>
(limite superior) não é possível adicionarAnimal
ou qualquer subtipo (exceto nulo).
Lendo listas limitadas
Ao ler listas de limite inferior e superior, lembre-se disto:
List super Animal>
: Os itens recuperados de uma lista de limite inferior são de tipo indeterminado atéObject
. A fundição é necessária para que este item seja usado comoAnimal
.
List extends Animal>
: Sabe-se que os itens recuperados são pelo menosAnimal
então nenhuma conversão é necessária para tratá-los comoAnimal
.
Um exemplo de listas de limite superior e inferior
Imagine que você tem um método para adicionar um Animal
para uma lista e outro método para processar animais de uma lista:
void addAnimal(List super Animal> animals, Animal animal) {
animals.add(animal); // This is valid.
}
Animal getAnimal(List extends Animal> animals, int index) {
return animals.get(index); // No casting needed, returns Animal type.
}
Nesta configuração:
addAnimal
pode aceitar umList
,List
etc., porque todos eles podem ter umAnimal
.getAnimal
pode trabalhar comList
,List
etc., retornando com segurançaAnimal
ou qualquer subtipo sem arriscarClassCastException
.
Isso mostra como os genéricos Java usam o extends
e super
palavras-chave para controlar quais operações são seguras em relação à leitura e escrita, alinhando com as operações pretendidas do seu código.
Conclusão
Saber como aplicar conceitos avançados de genéricos o ajudará a criar componentes robustos e APIs Java. Vamos recapitular os pontos mais importantes deste artigo.
Parâmetros de tipo limitado
Você aprendeu que os parâmetros de tipo limitado limitam os tipos permitidos em genéricos a subclasses ou interfaces específicas, melhorando a segurança e a funcionalidade do tipo.
Curingas
Use curingas (? extends
e ? super
) para permitir que métodos genéricos manipulem parâmetros de vários tipos, adicionando flexibilidade ao gerenciar covariância e contravariância. Nos genéricos, os curingas permitem que os métodos funcionem com coleções de tipos desconhecidos. Esse recurso é crucial para lidar com a variação nos parâmetros do método.
Apagamento de tipo
Esse recurso avançado permite compatibilidade com versões anteriores, removendo informações de tipo genérico em tempo de execução, o que faz com que detalhes genéricos não sejam mantidos após a compilação.
Métodos genéricos e inferência de tipo
A inferência de tipo reduz o detalhamento do seu código, permitindo que o compilador deduza tipos do contexto e simplifique o código, especialmente do Java 7 em diante.
Limites múltiplos em genéricos Java
Use vários limites para impor condições de vários tipos (por exemplo,
). Garantir que os parâmetros atendam a todos os requisitos especificados promove segurança funcional e de tipo.
Limites inferiores
Eles suportam operações de gravação, permitindo adições de (em nosso exemplo) Animal
e seus subtipos. Recupera itens reconhecidos como Object
exigindo conversão para usos específicos devido à natureza geral dos limites inferiores.
Limites superiores
Isso facilita as operações de leitura, garantindo que todos os itens recuperados sejam pelo menos (no nosso exemplo) Animal
eliminando a necessidade de fundição. Restringe adições (exceto nulas) para manter a integridade do tipo, destacando a natureza restritiva dos limites superiores.