Generics, inferência de tipos e reificação no Java 7

Generics, inferência de tipos e reificação no Java 7
peas
peas

Compartilhe

Muito tem se falado sobre o Java 7 SE e que mudanças na linguagem essa versão poderá trazer. Alex Miller criou um excelente post com muito links para JSRs e blogs sobre as propostas para a linguagem. Peter Ahe publicou também um interessante wish list.

Maneiras alternativas de criarmos coleções usando uma sintaxe mais enxuta já foram discutidas por Stephen Colebourne, Peter Ahe e Rafael Ferreira. Gostaria de salientar que o Java 5 já trouxe alguns métodos interessantes na Collections com essa finalidade. Exemplos são quando queremos criar uma coleção vazia ou com apenas um elemento:

 List<String> x = Collections.emptyList(); List<Integer> y = Collections.singletonList(5); 
Banner da Escola de Inovação e Gestão: Matricula-se na escola de Inovação e Gestão. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!

Existem métodos análogos para a criação de conjuntos e mapas. A assinatura do método emptyList é <T> List<T> emptyList(). É interessante que a linguagem infere, descobrindo que nesse primeiro caso T deve ser String. Mas isso nem sempre acontece:

 static void metodo(List<String> lista) { // faz alguma coisa } // dentro do main: metodo(Collections.emptyList()); 
``` A invocação acima não compila, pois tenta fazer `T` como `Object`! Algumas pessoas acham que [isso é um bug](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6293352), mas o pessoal da Sun decidiu por não tentar inferir o tipo em determinadas situações. Na verdade, o compilador só tenta inferir o tipo em dois específicos casos: na clausula de `return` ou em uma atribuição.

A especificação da linguagem Java tem uma sintaxe especial no caso de você querer indicar qual é o tipo que deve ser utilizado em uma invocação de método genérico:

```java
 metodo(Collections.<String>emptyList()); 

Pronto! Agora o Java sabe que T deve ser String nessa invocação, e nosso código passa a compilar. Uma sintaxe esdruxula e pouco comum.

Enquanto todo mundo comenta sobre as closures do Java 7, sem dúvida meu principal interesse sobre o Java 7 é a reificação de tipos genéricos, isso é, em tempo de execução, poder determinar os tipos parametrizados de um objeto. Hoje em dia isso não é possível por causa da erasure, que mantém a compatibilidade com o código pré-generics: um objeto não sabe, em tempo de execução, quais são os tipos que foram usados nos seus parâmetros durante sua instanciação. Isso cria algumas clássicas questões nos fóruns, como "porque não posso criar uma array de T?" ou "Porque não posso usar T.class?". Muitas pessoas consideram até a hipótese de quebrar a compatibilidade binária do Java, e fazem propostas interessantes para resolver esse problema.

Creio que o Java 7 trará muitas novas surpresas, algumas interessantes como as closures, outras infames como o suporte a literais XML dentro da linguagem. Só espero que eles continuem com a premissa do Java, de deixá-la legível e simples, e não façam como no C++, onde todo novo recurso interessante foi adicionado, tornando a linguagem de difícil legibilidade em alguns casos.

Veja outros artigos sobre Inovação & Gestão