No código acima, temos uma Runtime Exception.
Minha dúvida é por quê isso gera uma Runtime ao invés de um Compilation-time.
Por quê o compilador não identifica esse cast absurdo?
O compilador entende que a expressão “new Tree()” é uma expressão cujo tipo é Tree (ou seja, new Tree, nesse ponto, poderia retornar um objeto de qualquer classe que fosse Tree ou até mesmo uma subclasse de Tree). É por isso que ele força um run-time check em vez de indicar um erro de compilação.
Treet=(Redwood)newTree();
é equivalente, para o compilador, a uma coisa como:
Concordo com você que neste caso em especial o compilador deveria indicar que o tipo dessa expressão não pode ser uma subclasse de Tree e portanto o cast pode ser provado estaticamente que vai sempre ser incorreto. Veja se o mesmo problema ocorre com o compilador do Eclipse (que não é o javac, que é usado pelo NetBeans).
C
cvinicius
Quando fiz a prova não lembro de todas as questões sobre Cast, mas é sempre bom ficar atento porque tem algumas que confundem, como este exemplo acima.
Até mais.
bruno_7317
Mesmo compilation-fail no eclipse.
Mas como você sabe que o compilador lê meu códigoTree t = (Redwood) new Tree(); como public static Tree newTree() { return new Redwood(); }
...
Tree t = (Redwood) newTree();
Isso seria o mesmo que dizer que Tree é uma subclasse de Redwood, o que continua sendo um absurdo. Não entendi.
E
entanglement
É assim.
Ao ler a expressão, ele cria uma árvore sintática abstrata (AST, “Abstract Syntax Tree”) e vai atribuindo os tipos a cada nó dessa árvore. Ao ver a expressão “new Tree()”, ele cria um nó para essa expressão, cujo tipo é Tree.
Só que o compilador não guarda a informação de que o tipo dessa expressão é EXATAMENTE Tree (não pode ser uma subclasse de Tree). Acho que isso é feito porque o caso em que é necessário saber esse tipo de informação é só necessário quando usar algumas particularidades do Generics (lembra-se daquelas histórias de “super T” ou “extends T” que você vê às vezes? Pois é…)
Portanto, como você está fazendo um “upcast” (cast de uma expressão cujo tipo é Tree, ou seja, o objeto retornado por essa expressão tem o tipo Tree ou então um tipo que é uma subclasse de Tree), ele simplesmente põe um “run-time check” em vez de reclamar que o cast não pode ser efetuado. E é por isso que eu pus a expressão equivalente “newTree” porque o compilador guarda exatamente a mesma descrição para o tipo dessa expressão para “new Tree()” ou “Tree newTree()”.
bruno_7317
entanglement:
Ao ler a expressão, ele cria uma árvore sintática abstrata (AST, “Abstract Syntax Tree”) e vai atribuindo os tipos a cada nó dessa árvore. Ao ver a expressão “new Tree()”, ele cria um nó para essa expressão, cujo tipo é Tree.
É grego? rs
Entendi tudo. Obrigado, cara!
E
entanglement
O código abaixo roda e funciona direitinho. Por que é que você disse que ele é absurdo?