Pessoal, qual o problema com o trecho de código abaixo:
classTeste{publicstaticvoidmain(String...args){List<Integer>list=newArrayList<Integer>();for(inti=0;i<4;i++)list.add(i);Integer[]array=(Integer[])list.toArray();// essa linha dá classCastException}}
Até onde entendo um Object[] pode ser convertido pra um Integer[]..ou não?
toArray() - sem parâmetros - retorna um Object[]. Ao dar cast para Integer[], você vai ter um ClassCastException.
toArray(Object[]) popula o array dado como parâmetro, ou, se não houver espaço neste, cria reflexivamente um novo array do mesmo tipo do que você passou como parâmetro.
V
Vini_Fernandes
Entao cara, o negocio é que o Java nao realiza o cast dos elementos do array Object[]. Imagine a seguinte situacao:
e agora
finalmente
Grandes problemas!!!
Abracao.
P
phpinheiro
Teste este código:
Objecta=newObject();Integerb=(Integer)a;
Dá o mesmo exception.
R
rodrigo.bossini
Entao cara, o negocio é que o Java nao realiza o cast dos elementos do array Object[]. Imagine a seguinte situacao: Integer[] x = {1, 2, 3}; e agora Object[] y = {1, "vinicius", new File()};
Não não, aqui não deu erro, e acho que nem deveria, isso nada mais é que um downcast.
É possível converter uma super para uma subclasse ?
Não seria ao contrário?
Pq a subclasse tem membros que a super não tem, por serem da sub.
É justamente pra isso que serve o downcast. Você avisa pro compilador que está disposto a perder a precisão de um "super-objeto" pra poder usar
as funcionalides que só um "sub-objeto" pode ter. Caso não seja possível o downcast, aí vem a ClassCastException.
Converter uma subclasse pra uma superclasse não faz sentido, o compilador já faz isso sozinho.
V
Vini_Fernandes
Entao phpinheiro , o problema agora é outro. Aqui voce esta violando os fundamentos de herancao, em outros termos, um Integer é um Object, porem um Object nao é um Integer. E foi que voce disse ao compilador! Resumindo, o que voce codificou é análogo a seguinte instrução:
Integer inteiro = new Object();
E isto significa: um Object é um inteiro!
Abracao
R
rodrigo.bossini
E se eu tiver um método com um Object como parâmetro e quiser realizar operações da classe Integer nesse objeto.
Primeiro preciso converter o Object pra Integer, certo?
Ah sim, agora entendi.
Isso aqui funciona:
Object o = new Integer(2);
Integer i = (Integer) o;
R
rodrigo.bossini
Isso aqui tbm funciona:
Object []o = new Integer[2];
Integer []i = (Integer[]) o;
Agora a seguinte linha:
Integer[] array = (Integer[]) list.toArray();
o toArray() retorna um Object[]. Não é uma referência do tipo Object[] que aponta pra um Integer[]. De fato o objeto é um Object[]. Por isso não funciona. Certo?
V
Vini_Fernandes
Boa, garoto!! Isso mesmo!!
P
phpinheiro
Vixi…me confundi…
Não é a mesma coisa do meu exemplo? tirando que o meu exemplo é um Object, e o outro é um Object[].
Resultado:[code=xml]
Objects:
class java.lang.String
class java.lang.String
class java.lang.String
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at Cortar.main(Cortar.java:20)
[/code]
Se eu mudar o toArray para
return(T[])list.toArray(array);
A parte de Strings imprime
Strings:acenulle
Alguém sabe fazer a parte das Strings funcionar sem que eu tenha que mudar para esta linhas?
E imprimir somente:
[code=xml]Strings:
a
c
e
[/code]
V
victorwss
Evite o método toArray(), e sempre prefira toArray(Object[]).
O método toArray sempre-sempre-sempre retorna um Object[]. Isso não é um Integer[] nem um T[] e nem um Cachorro[].
O método toArray() na verdade foi mal-projetado (se bem que não poderia ter sido criado de forma diferente). Ele tem uma falha de segurança de tipos inerente do type-erasure - A JVM não sabe qual é o generic do List, logo não tem como saber qual é o tipo do array. Arrays são fortemente tipados, e não é bom trazer o problema do type-erasure para eles. Portanto, evite este método.
O toArray(Object[]) é exatamente a gambiarra que foi criada especificamente para contornar este problema da linguagem.
B
Bruno_Laturner
victorwss:
Evite o método toArray(), e sempre prefira toArray(Object[]).
Isso parece um daqueles ClassCastExceptions obscuros que na verdade vem de métodos bridge, que são aqueles métodos sintéticos inseridos pelo compilador que fazem casts para lidar com generics.
O compilador deve estar criando um método bridge assim:
E é este cast sintético que está gerando o seu ClassCastException.
O problema é a assinatura do método cortarNulos(T[]). Ele deve retornar Object[] e não T[].
V
Vini_Fernandes
Conforme em alguns post anteriores, o problema é que o método toArray(new Object[]) retorna um Object[], porem, seu metodo generico foi tipado para String e espera um retorno do tipo String[] e voce esta passando como retorno Object[].