segunda-feira, 25 de fevereiro de 2008

Genéricos em JAVA - Básico

Estudando JDBC, acabei tendo interesse em entender o que acontece quando usamos o Class.forName para carregar um Driver para um Database. Para isso, comecei a pesquisar na documentação da Sun, mais detalhes sobre a classe Class. Com isso acabei caindo no método getClass da classe Object (que retorna a classe de um objeto em execução).
Observando a definição deste método encontrei o código que segue abaixo:

public final Class<? extends Object> getClass()


Para começar a entender o código acima, tive que então estudar sobre tipos genéricos em Java para entender o "<? extends Object>".
Então abaixo segue o que entendi sobre os genéricos:

Em primeira instância pode-se notar que a utilização de genéricos tras algumas vantagens como:

1 - simplificar o código eliminando typecasts
2 - segurança na utilização de objetos, tornando ainda mais forte a tipagem do Java.

Vejamos o exemplo de código abaixo:


Map mapa = new HashMap();
List livros = new ArrayList();

livros.add(new Book(1, "java"));
livros.add(new Book(2, "Nietzche"));

mapa.put("livros", livros);
mapa.put(new Integer(0), "coisa que nao tem nada a ver");
Book x = (Book)((List)mapa.get("livros")).get(0); //pegando o livro de java do array list livros

System.out.println("Nome do livro:" + x.getName());


O código acima compila tranquilamente mesmo atribuindo coisas que não tem nada a ver com o contexto dentro do mapa "mapa".


No código acima podemos notar 2 desvantagens:
1 - código ruim em termos de legibilidade
2 - o código está permitindo construir um mapa com chaves e valores incompatíveis o que poderia
trazer dores de cabeça caso for necessário fazer uma iteração neste mapa. (poderia até usar um instanceof para tratar isso, poré, além de não ser boa idéia em termos de performance, os puristas de OO iriam dizer que o sistema está mal modelado, pois uma boa modelagem permite resolver isso com polimorfismo)

Para resolver estes problemas os genéricos do Java5 são utilizados no código conforme abaixo:

/* testes de tipos genericos em java */
Map<String, List<Book<> mapa = new HashMap<String, List<Book>>();
List<Book> livros = new ArrayList<Book>();

livros.add(new Book(1, "java"));
livros.add(new Book(2, "Nietzche"));

mapa.put("livros", livros);
mapa.put(new Integer(0), "coisa que nao tem nada a ver"); // este codigo ja nao compila mais
Book x = mapa.get("livros").get(0); // sem typecasts
System.out.println("Nome do livro:" + x.getName());

2 comentários:

  1. legal! so um detalhe: ach otu esquecestes um > antes declaracao do mapa no segundo codigo :+)

    ResponderExcluir