Exercicio Collection

Estou com uma dúvida no exercício abaixo eu pus no eclipse e compilei mas eu não entendi porque que a linha ArrayList<Rectangle> c = (ArrayList<Rectangle>)b; não lança uma exceção. Segue o código abaixo:

import java.util.*; class Shape{} class Circle extends Shape{} class Rectangle extends Shape{} public class Generics { public static void main(String[]args) { ArrayList<Circle> a = new ArrayList<Circle>(); a.add(new Circle()); ArrayList b = a; ArrayList<Rectangle> c = (ArrayList<Rectangle>)b; c.add(new Rectangle()); for(Object o : b) System.out.println(o); } }

Interessante.
Talvez tenha a ver com ambos estenderem Shape.

Mas pelo que eu entendi ambos estendem a classe Shape, mas não há uma relação direta entre Circle e Rectangle então no caso um ArrayList de Circle esta querendo ser incluído em um ArrayList de Rectangle e eu acho pelo que estudei quando você tenta atribuir um objeto de um tipo para um de outro tipo sem uma relação direta e faz o cast lança uma exceção de ClassCastException pelo que eu me lembro é isso e por isso a dúvida.

o “c” retangulo está recebendo um “b”.

mas

o “b” recebeu um “a” que é circulo.

então

está fazendo um cats do circulo para o retangulo antes de atribuir a “c”.

Mas tipo debugando o código depois da execução da linha 11 a variável b fica com esse valor br.com.blackbelt.certificacao.Circle@122cdb6 esse valor é um Circle e vai se adicionado a um ArrayList de Rectangle ai minha dúvida mesmo com cast não deveria ser possível

Eu acho q não lança exceção pq b não usa generics. Se vc tentar fazer o cast d a, por exemplo, dará erro d compilação. E se no for vc usar a ou c, lançará uma exceção.

And the winner is…

É isso mesmo, quando vc tem um ArrayList que não é generic, praticamente todas as conversões são possíveis. Fizeram isso por questões de compatibilidade.
Entretanto, tentar usar uma coleção assim irá disparar um ClassCastException.

Você também deve ter recebido um warning durante a compilação avisando que você está usando uma classe sem generics, e que isso é perigoso.

Se quiser ler mais sobre o assunto:
http://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html

PS: Apenas para ninguém aqui sair fazendo má prática, embora não esteja relacionado exatamente com o tópico.

O jeito ideal de declarar uma lista é pela interface:

E não:

Mais informações:
http://www.guj.com.br/java/55387-duvida-basica-sobre-oo---instancias-#290673