1
resposta

Casting múltiplos com interfaces e classes

Na questão 06 da aula 04 temos a seguinte questão:

interface Z {}
interface W {}
interface Y extends Z, W {}
class B {}
class C extends B implements Y {}
class D extends B implements Z, W {}
class E extends C {}
class A {
    public static void main(String[] args) {
        D d = (D) (Y) (B) new D();
    }
}

Na resposta diz que Compila mas dá Exception ao executar. Não consegui entender por que compila. Na parte ...(D) (Y)... não deveria dar erro: "cannot convert from Y to D"? pois esse erro dá se eu usar o seguinte código:

D d = (Y) (B) new D();

Qual a diferença? Se não é possível casting de Y para D por que pode ter ...(D)(Y)... no meio do casting? Com casting múltiplos assim, como o compilador faz a verificação? Alguém poderia fazer o passo a passo da verificação do compilador? Quebrar essa linha em partes? Obrigado

1 resposta

Olá, Joab!

A questão é que o compilador do Java vai apenas olhar o último casting, né?

No código

D d = (D) (Y) (B) new D();

é feito um casting para (D). E você pode colocar um (D) na variável d do tipo D. Tudo tranquilo para o compilador: você pode colocar um D num D.

Em tempo de execução, a JVM consegue converter um D para um B, porque D é filho de B. Nem precisaria de casting, na verdade.

Agora, na hora de converter o D* para Y, a JVM vai descobrir que não dá! E dá o ClassCastException: D cannot be cast to Y

* O D está com uma máscara de B mas é um D lá no fundinho de sua alma :)


No código

D d = (Y) (B) new D();

o compilador vê que tem um casting para Y sendo colocado numa váriável do tipo D.

Opa, pera lá! Não dá pra por um Y num D. A hierarquia lá não permite.


Essa questão é um exemplo de que é melhor olhar o código no main antes.

A minha primeira ideia é desenhar a hierarquia de todas as interfaces e classes. Mas não precisa, né?