Type casting no objeto  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
hlegius
JavaChild
[Avatar]

Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline

Salve povo !

Tenho uma classe definida por uma interface. Esta classe (ou estas, por isso a interface) é injetada em um "Autenticador" onde eu via Reflection pego o nome da tal classe para fazer uma factory ali.
O problema é que o Eclipse fica com uma mensagem de aviso sobre meu type casting e eu como bom iniciante em Java não sei o que poderia fazer para torná-lo correto. Segue:



Authentication é minha interface
this.autenticado é o tal objeto recebido, no caso uma classe que implemente a interface - e é dela que eu quero saber o nome


Eu realmente não sei o que está zuado para que possa tornar esse casting inseguro :/ Dicas ?


Abraços !

http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution
[WWW] [MSN] [ICQ]
andeb
Thread.start()

Membro desde: 17/05/2009 21:01:04
Mensagens: 47
Localização: Blumenau
Offline

Essa warning é meia estranha, me corrijam caso eu fale besteira, pelo que entendi de acordo com a domentação, é que o método getClass de Object retorna a class do objeto definido em runtime. Sendo assim, acredito eu, não seria lógico usar polimorfismo para quando dar um getClass() em CharSequence retornar um objeto Class<CharSequence> quando na verdade eu possuo uma instância de String definida em runtime, daí o que o compilador faz é usar um wildcard com extends. O que é definido na documentação é que o compilador retorna sempre um <? extend X> onde X é o tipo da variável de referência. Ex.:



Para resolver seria só a declaração do atributo para:


ou adicionar uma supress warning, já que nesse caso é seguro:



Até agora não achei um bom motivo pro java acusar como warning isso, acho mais uma gambizera do tipo genéricos que foi pensando pra ser utilizados em coleções que se esqueceu do resto.

Sei que só enrolei e que não respondi sua dúvida mas talvez ajude pra algo isto
Creio que a dúvida está em como utilizar corretamente o wildcard.

Caso falei muita alguma besteira, por favor me corrijam.

"it's not what you know, it's when you know it"
Bruno Laturner
GUJ Expert
[Avatar]

Membro desde: 18/02/2008 16:17:53
Mensagens: 3002
Offline

Tô meio sem cabeça pra pensar do por que ele dá um warning, mas o que estou estranhando é por que você está usando Reflection e Generics. O que esse método deve fazer?

A resposta acima foi achada em menos de 5 minutos no google.
The prisoner falls in love with his chains. --E.W. Dijkstra
[WWW]
marcobiscaro2112
JWizard

Membro desde: 01/12/2008 11:56:04
Mensagens: 2408
Localização: São Paulo - SP
Offline

Realmente ele retornar o tipo em runtime. Por exemplo, se você tem um método:

Esse trecho vai fazer o que se espera que ele faça, independentemente do tipo de argumento que você passar:

E isso só funciona porque o método getClass() de Object não retornar Object.class e sim o objecto Class de runtime (um Class de algo que estende Object, portanto um Class<? extends Object> ).

No seu caso, a mesma coisa ocorre: como a classe é definida em Runtime, ele não retornará Authentication.class e sim o objeto Class da implementação de Authentication (portanto, um Class<? extends Authentication> ).

Ok, mas e daí? Por que o cast gera um warning? Simples: porque um SeiLaOQue<T> pode não ser o mesmo que um SeiLaOQue<? extends T>. Um exemplo: suponhamos que temos um List de Object. Perceba que isso pode ser interpretado de duas formas:

1. Uma lista que carrega qualquer objeto (podemos ter, por exemplo, uma String, um Integer e um Double).
2. Uma lista que carrega um único tipo de objeto (por exemplo, uma lista que carrega somente Double, ou uma lista que carrega somente String que, por sua vez, são um tipo de Object).

Apesar de String estender Object, um List<String> não estende um List<Object> justamente por causa do que foi citado acima: a lista de String carrega apenas Strings, enquanto uma lista de Object carrega qualquer tipo de objeto.

Uma consequência disso é que o código abaixo não compila:


Imagine que queremos um código para imprimir qualquer List de números:

E depois chamamos assim:

O código acima não resolve nosso problema. Porque? Pois, como já dito, uma lista de inteiros não é uma lista de números. A solução? Fazer o mesmo que o getClass() faz: usar um wildcard.

Agora funciona. Entendeu o porque do warning? Porque uma Class<Authentication> não é, necessariamente um Class<? extends Authentication>.

Mais informações: http://java.sun.com/docs/books/tutorial/extra/generics/index.html

This message was edited 3 times. Last update was at 21/01/2010 08:46:20


Marco Biscaro.

Seja livre!

Você sabia que provavelmente há milhares de arquivos duplicados no seu computador?

Ei... você está usando DefaultTableModel no seu projeto?? Não faça isso! Veja: http://www.guj.com.br/posts/list/15/199067.java#1001295
[Email] [WWW] [MSN]
hlegius
JavaChild
[Avatar]

Membro desde: 07/05/2006 14:29:25
Mensagens: 126
Localização: Guarulhos, SP
Offline

andeb, Bruno Laturner e marcobiscaro2112,

Caramba ! Excelentes explicações, nem esperava por tantos detalhes nas explicações ! =D

Bruno Laturner,
Meu objetivo com ele seria :

. O método recebe a interface Authentication
. Descobre qual o nome da classe (pois eu conheço apenas a interface) em runtime
. Com o seu nome em mãos, define como ela será tratada. É factory

marcobiscaro2112,
Ao que entendi, é inseguro eu definir Foobar<Interface> pois pode acabar retornando-me algo inesperado sendo ideal deixar o tipo bem definido.

Vou ler o link que me passou para pegar mais possíveis detalhes =D


Muito obrigado galera

http://programe.me
Zend Certified Engineer
ArchLinux - A simple lightweight Linux Distribution
[WWW] [MSN] [ICQ]
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team