toArray dúvida

Pessoal, qual o problema com o trecho de código abaixo:

[code]
class Teste{
public static void main (String… args){
List list = new ArrayList ();
for ( int i = 0; i < 4; i++)
list.add(i);

   Integer[] array = (Integer[]) list.toArray(); // essa linha dá classCastException

}
}[/code]
Até onde entendo um Object[] pode ser convertido pra um Integer[]…ou não?

É 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.

assim funciona

    public static void main(String... args)
    {
        List&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;();
        for (Integer i = 0; i &lt; 4; i++) {
            list.add(i);
        }

        Integer[] array = new Integer[4];
        list.toArray(array);
    }
Integer[] array = (Integer[]) list.toArray(new Integer[list.size()]);

Não precisei usar cast , aqui funcionou assim:

public static void main (String[] args){  
	       ArrayList <Integer> list = new ArrayList <Integer>();  
	       for ( int i = 0; i < 4; i++) { 
	              list.add(i);  
	       }
	       Integer[] array = list.toArray(new Integer[list.size()]);
	       
	       for(Integer i : array){
	    	   System.out.println(i);
	       }
	   } 

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.

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.

Teste este código:

    Object a = new Object();
    Integer b = (Integer) a;

Dá o mesmo exception.

Essa me pareceu a explicação mais plausível.

[quote]Teste este código:

[code] 1. Object a = new Object();
2. Integer b = (Integer) a;

Object a = new Object(); Integer b = (Integer) a;[/code]

Dá o mesmo exception. [/quote]

Não não, aqui não deu erro, e acho que nem deveria, isso nada mais é que um downcast.

[quote]É 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.[/quote]

É 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.

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

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:

           [code]Object o = new Integer(2);
	Integer i = (Integer) o;[/code]

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?

Boa, garoto!! Isso mesmo!!

Vixi…me confundi…

Não é a mesma coisa do meu exemplo? tirando que o meu exemplo é um Object, e o outro é um Object[].

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html

Rsr…quer ver voce ficar confuso agora:

Depende como voce esta abordando o problema! Voce poderia ter inicialmente:

Que é equivalente a primeira instrucao que escrevi!

Exatamente Vini, dá na mesma. Isso que eu quis dizer.

estou falando porque vc mencionou anteriormente que o meu exemplo era outro problema

Era outra abordagem, realmente…mas o problema é o mesmo.

Tenho um problema parecido mas pouco mais complicado:

[code]import java.util.ArrayList;

public class Cortar
{
public static void main(String[] args)
{
String[] stringArray = new String[5];
stringArray[0] = “a”;
stringArray[2] = “c”;
stringArray[4] = “e”;

  Object[] objectArray = cortarNulos(stringArray);

  System.out.println("Objects: ");
  for (Object object : objectArray)
  {
     System.out.println(object.getClass());
  }

  String[] stringArray2 = cortarNulos(stringArray);

  System.out.println("Strings: ");
  for (String s : stringArray2)
  {
     System.out.println(s);
  }

}

public static T[] cortarNulos(T[] array)
{
ArrayList list = new ArrayList(array.length);
for (T a : array)
{
if (a != null)
list.add(a);
}

  return (T[]) list.toArray();

}
}
[/code]Resultado: 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)

Se eu mudar o toArray para

A parte de Strings imprime

Strings: a c e null e

Alguém sabe fazer a parte das Strings funcionar sem que eu tenha que mudar para esta linhas?

[code]String[] stringArray2 = cortarNulos(stringArray, new String[0]);

public static T[] cortarNulos(T[] array, T[] array2)

return (T[]) list.toArray(array2);
[/code]

E imprimir somente:

Strings: a c e

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.

Sm, mas não resolve meu problema:

[code]return (T[]) list.toArray(new Object[0]);

Exception in thread “main” java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
[/code]