Compilador doido? Questão de prova. (Resolvido)  XML
Índice dos Fóruns » Certificação Java
Autor Mensagem
bruno_7317
JavaBaby
[Avatar]

Membro desde: 15/04/2008 11:19:24
Mensagens: 96
Localização: Brasília/DF
Offline



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?

This message was edited 1 time. Last update was at 22/12/2011 14:51:45

cvinicius
JavaEvangelist

Membro desde: 18/04/2008 16:35:05
Mensagens: 433
Localização: SP
Offline

Boa tarde

Então bruno, ele compila porque a classe Radwood herda a classe Tree, por isso a compilação ocorre.

Falou.

This message was edited 1 time. Last update was at 22/12/2011 14:26:01


Sun Certified Java Programmer 5
Oracle Certified Associate, Java SE
Oracle Certified Professional Java EE 5 Web Component Developer
bruno_7317
JavaBaby
[Avatar]

Membro desde: 15/04/2008 11:19:24
Mensagens: 96
Localização: Brasília/DF
Offline

Claro que não!

Um cast do tipo
É um absurdo sem tamanho!
entanglement
GUJ Hacker

Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline

Um tiipo de questão assim, rigorosamente, não deveria cair na prova, por que é uma coisa que está "escrita em letras miúdas na especificação".

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#238146

Some casts result in an error at compile time. Some casts can be proven, at compile time, always to be correct at run time. For example, it is always correct to convert a value of a class type to the type of its superclass; such a cast should require no special action at run time. Finally, some casts cannot be proven to be either always correct or always incorrect at compile time. Such casts require a test at run time. See for §5.5 details.


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.



é 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).


cvinicius
JavaEvangelist

Membro desde: 18/04/2008 16:35:05
Mensagens: 433
Localização: SP
Offline


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.

Sun Certified Java Programmer 5
Oracle Certified Associate, Java SE
Oracle Certified Professional Java EE 5 Web Component Developer
bruno_7317
JavaBaby
[Avatar]

Membro desde: 15/04/2008 11:19:24
Mensagens: 96
Localização: Brasília/DF
Offline

Mesmo compilation-fail no eclipse.

Mas como você sabe que o compilador lê meu código como

Isso seria o mesmo que dizer que Tree é uma subclasse de Redwood, o que continua sendo um absurdo. Não entendi.

This message was edited 1 time. Last update was at 22/12/2011 14:24:55

entanglement
GUJ Hacker

Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline

É 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
JavaBaby
[Avatar]

Membro desde: 15/04/2008 11:19:24
Mensagens: 96
Localização: Brasília/DF
Offline

entanglement wrote:
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

entanglement wrote:
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()".

Entendi tudo. Obrigado, cara!

This message was edited 1 time. Last update was at 22/12/2011 14:41:29

entanglement
GUJ Hacker

Membro desde: 26/09/2009 09:18:56
Mensagens: 5750
Offline

O código abaixo roda e funciona direitinho. Por que é que você disse que ele é absurdo?
bruno_7317
JavaBaby
[Avatar]

Membro desde: 15/04/2008 11:19:24
Mensagens: 96
Localização: Brasília/DF
Offline

entanglement wrote:O código abaixo roda e funciona direitinho. Por que é que você disse que ele é absurdo?


O newTree pode retornar tanto um Tree quanto um Redwood, por isso ele deixa pra verificar em runtime.
Entendi. Obrigado novamente.
 
Índice dos Fóruns » Certificação Java
Ir para:   
Powered by JForum 2.1.8 © JForum Team