Generics

Aula
Estado
  • Permite variáveis e métodos a operar com diversos tipos garantindo segurança em compile-time
  • A abordagem pre-generics era utilizar uma classe mais alta na hierarquia, como Object
    • com isso você era obrigado a checar qual era o tipo da instância sempre que fazia alguma operação de um lugar mais baixo na hierarquia
    • nada garantia que o tipo passado era o mesmo em todos lugares

Avançado

  • Uma classe, método ou interface que utilize generics na sua assinatura, irá ter seu tipo compilado em Object.
    • isso garante compatibilidade com versões antigas
    • porém no momento da utilização do Object retornado o compilador aplica um cast para o tipo definido no generics
    • isso é seguro pois o compilador verifica type-safety antes de remover generics
notion image
  • O compilador cria uma método que funciona como ponte entre Object e o tipo definido
notion image
  • Existe uma sequencia de atribuições que podem causar erros em execução, mas não compilação
Após 'List values = foods;' o compilador não sabe mais qual é o tipo utilizado na lista
Após 'List values = foods;' o compilador não sabe mais qual é o tipo utilizado na lista

Wildcard

  • Em Java tudo tem um tipo. Ao criar uma coleção com List<?> list = ...; você terá uma lista que só poderá ser acrescida de null, ou seja, uma lista readonly
  • Permite transformar uma coleção — que por padrão é invariate — em uma covariante mais segura, definindo upper and lower boundaries
  • Uma coleção com upper boundaries só pode conter instâncias de classes que estendam um tipo Y. (e.g. List<? extends Product> onde o maior ponto da hierarquia permitido é Product.)
 
Upper bound
Upper bound
  • Uma coleção com lower boundaries só pode conter instâncias de um tipo X ou qualquer tipo que o tipo X estenda. (e.g. List<? super Food> onde o menor ponto da hierarquia permitido é Food.)
    •  
Lower bound
Lower bound