15.7. Métodos genéricos

Um tipo diz-se genérico quando a sua definição envolve uma ou mais variáveis de tipo, que são instanciadas quando o tipo é usado na declaração de variáveis e na criação de objetos.

Por exemplo, ArrayList<E> é um tipo genérico pois quando criamos um objeto deste tipo temos que instanciar a variável E (variável de tipo).

Isto permite que se use uma só definição para a representação de vários tipos – tantos quantos os valores possíveis para as variáveis de tipo.

Esta noção de genérico também se aplica a métodos individualmente – podemos definir um método que deixa em aberto um ou mais tipos através da utilização de variáveis de tipo.

Vamos então perceber a utilidade deste conceito aplicado a métodos.

Queremos um método para ver se duas listas são iguais.

1ª tentativa:

Este método não é muito útil pois, como já deve adivinhar, exige que se instanciem os parâmetros com listas de Object. Das invocações no método main que se segue, só a terceira está correta:

Gostaríamos que o método aceitasse também listas de elementos de quaisquer tipos.

2ª tentativa:

Esta versão já aceita listas de elementos de qualquer tipo. Até aceita duas listas cujos elementos são de tipos incomparáveis (por exemplo, Integer e Jogo).

 

15.7.1. Parâmetros de tipo

Se quisermos garantir que os parâmetros a e b representam listas de elementos do mesmo tipo e que esse tipo pode ser qualquer, teremos que usar um parâmetro de tipo, tornando o método genérico.

Última tentativa:

 

Indicamos que o método é genérico colocando < T > antes do tipo de retorno do método.

Por ser um parâmetro de tipo, T pode representar qualquer tipo; usamo-lo nos dois parâmetros a e b para obrigar a que os elementos dessas listas tenham exatamente o mesmo tipo.

Ao invocar um método genérico, não explicitamos qual o tipo que instancia T. O compilador faz isso por nós.

 

Um método genérico pode ter um ou mais parâmetros de tipo. Um exemplo com dois parâmetros de tipo:

Exemplos de invocação:

 

15.7.2. Parâmetros de tipo bounded

Podemos restringir os parâmetros de tipo de um método genérico a um subconjunto dos tipos Java. Fazemos isso usando parâmetros de tipo bounded.

 

Método genérico para ver se os elementos de uma lista são o dobro dos de outra:

Aqui o parâmetro de tipo é bounded pois queremos restringir o tipo dos elementos das listas parâmetro – têm que ser números.

Neste último método, as listas a e b têm que ter exatamente o mesmo tipo de elementos. Se quisermos que possam ser tipos diferentes, embora ambos subtipos de Number, poderíamos fazer assim:

 

15.7.3. Exemplos de métodos genéricos na biblioteca Java

No interface Collection, do pacote java.util, temos, por exemplo:

 

 


 

Anterior: 15.6. Tipos genéricos e sub-tipos

Seguinte: 16. Classes abstratas