Um passeio pelo Java 5 - Generics - Parte II
No artigo passado falei sobre: laço for melhorado, Autoboxing/Unboxing, enumerações (Enums), métodos com número de argumentos...
Estatísticas:










votos: 2
Serviços:

Um passeio pelo Java 5
Parte II – Generics
Interoperabilidade com Código Legado
Considere a atribuição:
Collection c = new ArrayList
Ela é permitida para garantir um certo grau de compatibilidade entre as versões da linguagem (afinal todo código Java escrito até hoje foi sem generics). Quando um tipo genérico como Collection é utilizado sem parâmetro de tipo é chamado um raw type. Porém, o uso deste artifício deve ser feito com muito cuidado!
Vejamos seus desdobramentos na linha abaixo:
c.add(new Integer(10)); //unchecked warning
O compilador não acusará erro mas emitirá um aviso. O aviso é necessário porque o compilador não é capaz de garantir a corretude do resultado. Mas a possibilidade de se incluir um inteiro numa lista de strings não deveria ser um erro? Teoricamente sim, mas, na prática, se é necessário que código genérico opere com código legado isto deve ser permitido. Vejamos outro exemplo:
ArrayList
Dica
Dica 2. Quando usar métodos
genéricos ou wildcards?
Use wildcard quando na assinatura do método o tipo
paramétrico aparecer somente uma vez, ou seja, não há interdependência de tipos
(nem de retorno, nem de argumentos).
public
Qual a melhor opção para os métodos acima? O
parâmetro T está sendo usado neste caso apenas para prover polimorfismo e
permitir que o método seja invocado com tipos diferentes. Use wildcards quando
precisar representar tipos flexíveis, que é o que pretende-se expressar aqui.
“Métodos genéricos permitem que os
tipos paramétricos sejam utilizados para expressar dependências entre tipos de
argumentos e/ou seu tipo de retorno. Se não existe tal dependência um método
genérico não deve ser empregado.”
public static
Estes métodos são exemplos de dependência do
parâmetro de tipo. No primeiro, a dependência está no tipo de retorno (sim, o
tipo de retorno pode ser variável !!) e no segundo a lista de origem (src) deve
ser de algum subtipo da lista de destino (dest).
O compilador não consegue garantir que c contenha apenas objetos Float e emite novamente um aviso. Fica a cargo do programador satisfazer os contratos estabelecidos e assim, por exemplo, prezar para que contenha uma coleção de números.
Chamar código legado a partir de código genérico é intrinsecamente perigoso! Uma vez que você mistura código genérico com código não genérico todas as garantias de segurança que usualmente um código genérico provê são perdidas. Entretanto, ainda assim é melhor do que não usar código genérico algum.
Casts, Arrays e Literais de Classe
O que o seguinte código irá imprimir?
List
List
System.out.println(l1.getClass() == l2.getClass());
Você pode ficar tentado a dizer que será false mas na verdade é true. Todas as instâncias de uma classe genérica compartilham a mesma meta-classe (ou run-time class) independentemente dos valores atuais dos seus parâmetros de tipo (tal como ocorre com classes não genéricas). Uma conseqüência disso é que em variáveis e métodos estáticos, por serem compartilhados por todas as instâncias, não pode haver referências a parâmetros de tipo.
Uma outra implicação é que não faz sentido perguntar para uma instância se esta é uma instância de um tipo particular. O código:
Collection cs = new ArrayList
if(cs instanceof Collection
é ilegal, bem como fazer os casts
Collection
ou
Variáveis de tipo não existem em tempo de execução. Em ambos os casos o compilador não pode garantir a conversão.
Não é permitida, por questões de segurança, a criação de arrays de tipos genéricos. Então as seguintes tentativas não são válidas
List
List
List[] L3 = new List
A única opção possível é a criação de (unbounded) wildcard arrays. Por exemplo
List[] lsa = new List[10]; //OK - array de unbounded wildcard
lsa[0] = new ArrayList
lsa[1] = new LinkedList
List
li.add(new Integer(10));
lsa[3] = li;
Integer xx = (Integer) lsa[3].get(0); //É necessário um cast
Dica
Dica
Generics são implementados pelo
compilador através de um mecanismo de conversão chamado erasure. Pode-se pensar
neste como uma tradução source-to-source onde, basicamente, todas as
informações de tipos genéricos são “apagadas“. Toda informação de tipo
entre <> é removida, então, por exemplo, List
Esse funcionamento explica porque uma
classe genérica é compartilhada por todas as suas instâncias e também porque
operações de verificação ou conversão de tipos genéricos não funcionam.
A classe java.lang.Class é genérica agora e é um bom exemplo de aplicação de generics além de coleções. Por exemplo, o tipo String.class é Class
Collection emps = sqlUtility.select(EmpInfo.class, “select * from emps”);
…
public static Collection select(Class c, String query)
{
Collection result = new ArrayList();
/* Executa a consulta */
for(/* Itera no resultset */)
{
Object item = c.newInstance(); //Retorna um Object
/* Utilize reflexao para setar os atributos do objeto baseado nos registros do banco*/
result.add(item); //Povoa a coleção com Objects
}
return result;
}
Collection
…
public static
{
Collection
/* Executa a consulta */
for(/* Itera no resultset */)
{
T item = c.newInstance(); //Retorna um EmpInfo
/* Utilize reflexao para setar os atributos do objeto baseado nos registros do banco*/
result.add(item); // Povoa a coleção com o tipo específico
}
return result;
}




Acoplamento fraco x Herança

Introdução ao Processo Unificado

Um passeio pelo Java 5 - Generics - Parte I

Um passeio pelo Java 5 - Generics - Parte II

Um passeio pelo Java 5 - Principais mudanças

Principais padrões J2EE para a construção de aplicações não distribuídas – Parte IV

Principais padrões J2EE para a construção de aplicações não distribuídas – Parte III

Principais padrões J2EE para a construção de aplicações não distribuídas – Parte II

Principais padrões J2EE para a construção de aplicações não distribuídas - Parte II

Principais padrões J2EE para a construção de aplicações não distribuídas - Parte II



Curso Online - Introdução ao AJAX Reverso

(tutorial) Aprenda a persistir dados em suas aplicações Java utilizando Hibernate

Desenvolvendo uma aplicação completa utilizando Swing

Introdução ao JDBC

Java Web: Saiba como Desenvolver Aplicações utilizando Spring, Hibernate e JSF na Prática

OLAP com o SQL Server

Introdução à Engenharia de Requisitos

Curso OnLine WebDesign - Desenvolvendo o layout de um WebSite passo a passo




[vídeo] Alterando dados no arquivo XML

[vídeo] Array no ViewData: Curso ASP.NET MVC 2.0 com Visual Studio 2010 - Parte 14

Mineração de Repositórios de Software: A Computação ajudando à Computação.

Boas-vindas

Boas-vindas

Mineração de Repositórios de Software: A Computação ajudando à Computação.

[vídeo] Teste Automatizado: Codificação do UserTest - Curso JEE e JSE – Loja Virtual Completa – Parte 17

[vídeo] MD5 com Delphi: Usando o Método Locar - Curso Aplicação Financeira Delphi 2009 e MySQ – Parte 32

[vídeo] MD5 com MySQL: Utilizando a função para Logar - Curso Aplicação Financeira Delphi 2009 e MySQL – Parte 31



Você está em:





Conheça os planos de créditos DevMedia e visualize esse post agora mesmo!

