Escolar Documentos
Profissional Documentos
Cultura Documentos
1
Java Generics
Os tipos de dados genéricos fazem sua estréia em
Java
POR HERVAL FREIRE DE A. JÚNIOR (HERVAL@CNNT.COM.BR)
Benefícios
É provável que todo programador já tenha se deparado com exceções de conversão
(ClassCastExceptions) ao percorrer uma coleções de objetos que (geralmente por acidente) contém
objetos de um tipo não esperado. Este problema ocorre graças à forma como a linguagem Java
utiliza-se do typecasting para criar estruturas de dados genéricas.
A listagem 1 mostra um exemplo de código utilizando-se da sintaxe atual da linguagem Java.
Graças à ausência de verificação de tipos forte, o código compila corretamente, mas um erro em
tempo de execução impede que o programa funcione como esperado.
l.add( i1 );
l.add( i2 );
l.add( i3 );
l.add( i4 );
while( numbers.hasNext() ) {
Integer integer = (Integer) numbers.next();
System.out.println( “” + integer.intValue() );
counter += integer.intValue();
}
abortar a compilação do programa, evitando que um trecho de código pouco visível venha a causar
uma grande dor de cabeça, no futuro.
Hello, Generics
A listagem 2 mostra um exemplo básico de utilização de tipos genéricos. Os comentários
mostram pontos onde o compilador acusa por erros, graças aos parâmetros indicando o tipo
esperado pela classe de coleção. Note que a sintaxe de parametrização é bastante simples: o tipo
utilizado de parâmetro é informado junto ao nome da classe (entre “<” e “>”), no momento de
instanciação dos objetos parametrizados. Este tipo é, a partir de então, utilizado em testes de
conversão (typecheckings) durante todo o processo de compilação, trazendo mais confiabilidade ao
código.
Vale citar que, apesar da existência de uma nova sintaxe, os bytecodes gerados por um programa
que utiliza-se de tipos genéricos são totalmente compatíveis com versões anteriores do Java: a nova
especificação define que o código compilado utilizando-se dos tipos parametrizados deve ser
convertido para código comum (sem marcadores de parametrização), ao final da compilação –
fazendo com que o mecanismo de verificação de tipos funcione sem afetar a compatibilidade de
código da linguagem como um todo.
Um segundo exemplo
As listagens a seguir demonstram um exemplo de implementação de uma interface genérica. A
interface MyInterface (listagem 3) define um método que trabalha com tipos genéricos – e é
implementada para realizar a comparação de elementos em uma lista (listagem 4). O exemplo,
3
retirado do artigo de divulgação da prévia dos tipos genéricos, é bastante simples e demonstra uma
interface que pode ser implementada para comparar dois objetos de mesmo tipo – seja qual for o
tipo – sem necessidade de verificações ou castings explícitos.
import java.util.List;
interface MyInterface<X> {
public boolean containsBoth(X a, X b);
}
import java.util.*;
public class MyList<X> extends LinkedList<X>
implements MyInterface<X> {
public boolean containsBoth(X a, X b) {
return (contains(a) && contains(b));
}
public static <A> void swap(List<A> list, int i, int j) {
A temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
/*
** main
*/
public static void main( String[] args) {
// create list and add elements
MyList<String> theList = new MyList<String>();
theList.add("one");
theList.add("two");
theList.add("three");
// print out the list's contents
System.out.println("");
System.out.println("The list's contents are:");
ListIterator<String> theIterator= theList.listIterator(0);
while (theIterator.hasNext()) {
System.out.println(theIterator.next());
}
System.out.println("");
// use the containsBoth method
if (theList.containsBoth("one", "two")) {
System.out.println("The list contains both \"one\" and \"two\"");
}
// use the swap method
swap(theList, 0, 2);
// print out the list's contents
System.out.println("");
System.out.println("The list's contents are:");
theIterator = theList.listIterator(0);
while (theIterator.hasNext()) {
System.out.println(theIterator.next());
}
System.out.println("");
} // main
} // MyList
4
A tabela abaixo mostra exemplos de utilização da nova sintaxe para a declaração de tipos, métodos,
interfaces e classes parametrizadas segundo a especificação da Sun.
Conclusão
Os tipos genéricos são, na pior das hipóteses, uma novidade bastante curiosa. Prova de que o
poder de transformação exercido pelo JCP (Java Community Process) da Sun tem lutado para
manter a linguagem Java sempre viva, com novos recursos a cada versão. A inclusão da diretiva
assert na versão 1.4 do JDK e a nova adição à sintaxe a ser consolidada no JDK 1.5 mostram que
ainda existe muito a ser explorado no longo processo de evolução (e maturação) da linguagem Java.
Que venham as novidades!
Referências
JSR-14 (Java Generics) -
PolyJ – Uma implementação não-oficial dos tipos genéricos -
Generics Early Access - http://developer.java.sun.com/developer/earlyAccess/adding_generics/