Dúvida genéricos

Olá pessoal estava testando alguns métodos envolvendo genéricos e me deparei com a seguinte situação:

//tenho este método que retorna um array lista de integer
public List<? extends Number> criarLista3() {
		
   return new ArrayList<Integer>();
}
	
public static void main(String[] args) {
	
  MetodosGenericos4 m = new MetodosGenericos4();
  //aqui está a dúvida estou fazendo um casting de ArrayList<Integer> para ArrayList<Number>
  //funcionou mas ao meu ver estaria errado pois não se pode fazer ArrayList<Number> = ArrayList<Integer>, tudo bem eu fiz o casting, mas o meu retorno está referenciando um ArrayList<Integer> isso não daria um erro????
  ArrayList<Number> lista1 = (ArrayList<Number>)m.criarLista3();
  lista1.add(new Float(12));
  System.out.println(lista1);
}

Ao meu ver deu certo esse casting por causa do seguinte tipo de retorno no método

public List<? extends Number> criarLista3() { ... }
//com isso eu posso fazer o casting do subtipo para o supertipo na hora de chamar o método

Estou correto nesta afirmação???
Se alguém puder me ajudar, ficarei grato.
Vinícius.

nao pode cara, vc jamais pode ter objetos diferentes dentro de um tipo generico, e se extends algo com generico nao pode adicionar

dar uma olhada nesse meu post.

Obrigado pela ajuda, mas aqui no eclipse esse código compilou.

nao cheguei a testar o codigo, porem estava falando desta parte do comentario:

realmente isso eh invalido.

Eh, ta complicado, estava fazendo uns testes aqui e teve uma coisa que me deixou mais confuso
porque isto funciona???

  ArrayList<? extends Number> lista2 = new ArrayList<Number>();  
  //casting de ArrayList<Number> para ArrayList<String> porque isso funciona????
  //a regra para casting de ArrayList é diferente da regra comum para casting de objetos????
  ArrayList<String> lista4 = (ArrayList<String>)lista2;
  lista4.add("1");
  lista4.add("2");
  lista4.add("3"); 
  System.out.println(lista4);

E funciona ?

Eu não consegui compilar …

eu tb nao conseguir compilar nao. As regras sao claras, para entender conjuntos + genericos tem que ler as regras, nao basta codificar e tentar entender na marra, tendo como base os erros do compilador.

funciona aqui no eclipse…
vou tentar compilar no java normal…
mas msm assim no eclipse eu configurei ele para compilar no java 6…

eu estou entendendo as regras…
mas quando vou compilar o resultado infrige a regra ai fica complicado…

compilei no java normal e ai não funcionou msm como eu esperava…
mas ai como que fica…
porq o eclipse faz isso???..
devo usar um outro editor para trabalhar com java???..

Cara, aqui num ta compilando não. rsrs

java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)
Teste.java:8: inconvertible types
found   : java.util.ArrayList&lt;capture#469 of ? extends java.lang.Number&gt;
required: java.util.ArrayList&lt;java.lang.String&gt;
                ArrayList&lt;String&gt; lista4 = (ArrayList&lt;String&gt;) lista2;
                                                               ^
1 error

[quote=vmsb11]funciona aqui no eclipse…
vou tentar compilar no java normal…
mas msm assim no eclipse eu configurei ele para compilar no java 6…[/quote]

genericos eh recurso a partir do java 1.5 e na 1.6 nao houve alteracoes em relacao as regras de comportamento com genericos, o fato eh simples nao colocar Uvas na caixa de Maças.

flw…

e o compilador ai foi bem objetivo em dizer aonde ta o erro, associado as regras vc mata a questao…

veja o link que passei, tem uma boa base sobre o assunto.

eh aqui deu o mesmo erro compilando no console…
amigo LPJava eu ja tinha lido o seu post, muito bom msm…
eu estou entendendo as regras mas fiquei na dúvida por causa desse teste que eu fiz no eclipse ontem…
pelo oque eu estou vendo o eclipse que está fazendo uma confusão…

testei no netbeans e realmente não funcionou…
alguem sabe me dizer porq o eclipse alguns códigos por mais que se pareçam bizarros eles compilam e funcionam???..
obs: estou usando o MyEclipse v 5.5

Mas o debate é legal.

Olha um comportamento engraçado que eu testei agora.

	public static void main(String[] args) {
		ArrayList&lt;Cachorro&gt; lista2 = new ArrayList&lt;Cachorro&gt;();
		lista2.add(new Cachorro("Snoopy"));
		ArrayList&lt;String&gt; lista4 = ((ArrayList&lt;String&gt;) (Object) lista2);
		lista4.add("1");
		lista4.add("2");
		lista4.add("3");
		System.out.println(lista4);
	}

Suponha que voce tenha uma classe cachorro ok ?
A saida:

[Cachorro@addbf1, 1, 2, 3]

Se eu faço o seguinte:

	public static void main(String[] args) {
		ArrayList&lt;Cachorro&gt; lista2 = new ArrayList&lt;Cachorro&gt;();
		lista2.add(new Cachorro("Snoopy"));
		ArrayList&lt;String&gt; lista4 = ((ArrayList&lt;String&gt;) (Object) lista2);
		lista4.add("1");
		lista4.add("2");
		lista4.add("3");
		lista4.get(0).toString();
		System.out.println(lista4);
	}

Colocando uma chamada a lista4.get(0) que é o objeto Cachorro.
Acontece um erro:

Exception in thread "main" java.lang.ClassCastException: Cachorro cannot be cast to java.lang.String
	at Teste.main(Teste.java:12)

Se chamo qualquer outro funciona beleza.

Não fui muito a fundo, mas parece que como na implementação do ArrayList ele armazena em um Object[] dentro da lista ele continua trabalhando mesmo com um objeto inválido.
E quando fazemos o get, por fazer referência ao generico String ele tenta fazer o cast e quebra tudo.

As vezes a gente encontra umas coisas engraçadas estudando estes exemplos.

Ué aquele primeiro codigo funcionou ake no NetBeans…
Não ta dando certo pq ele converteu pra ArrayList?

Isso ake tbm é valido?

ArrayList<? extends Number> c = new ArrayList();

Isto funciona mas vc não poderá adicionar nada na lista…

[quote=nbluis]Mas o debate é legal.

Olha um comportamento engraçado que eu testei agora.

	public static void main(String[] args) {
		ArrayList&lt;Cachorro&gt; lista2 = new ArrayList&lt;Cachorro&gt;();
		lista2.add(new Cachorro("Snoopy"));
		ArrayList&lt;String&gt; lista4 = ((ArrayList&lt;String&gt;) (Object) lista2);
		lista4.add("1");
		lista4.add("2");
		lista4.add("3");
		System.out.println(lista4);
	}

Suponha que voce tenha uma classe cachorro ok ?
A saida:

[Cachorro@addbf1, 1, 2, 3]

Se eu faço o seguinte:

	public static void main(String[] args) {
		ArrayList&lt;Cachorro&gt; lista2 = new ArrayList&lt;Cachorro&gt;();
		lista2.add(new Cachorro("Snoopy"));
		ArrayList&lt;String&gt; lista4 = ((ArrayList&lt;String&gt;) (Object) lista2);
		lista4.add("1");
		lista4.add("2");
		lista4.add("3");
		lista4.get(0).toString();
		System.out.println(lista4);
	}

Colocando uma chamada a lista4.get(0) que é o objeto Cachorro.
Acontece um erro:

Exception in thread "main" java.lang.ClassCastException: Cachorro cannot be cast to java.lang.String
	at Teste.main(Teste.java:12)

Se chamo qualquer outro funciona beleza.

Não fui muito a fundo, mas parece que como na implementação do ArrayList ele armazena em um Object[] dentro da lista ele continua trabalhando mesmo com um objeto inválido.
E quando fazemos o get, por fazer referência ao generico String ele tenta fazer o cast e quebra tudo.

As vezes a gente encontra umas coisas engraçadas estudando estes exemplos.[/quote]

Engraçado msm esses exemplos… por isso é válido algumas vezes abrir o código fonte e ver como que é a implementação das coleções no java…