Sr(s) estou estudando o capítulo 8 - Classe Internas do Livro da Katy Sierra e no exercício 8 da página 377, tem uma expressão que me deixou bilé, pelo fato de não entender o POR QUE. Segue abaixo a expressão:
(new Bar() {}).go();
Aqui agente pode ver que o código está criando uma classe anônima com base no Objeto Bar(), esse código foi compilado, mas, notem que não existe o ponto e virgula depois da chave de definição da classe anônima.
Pergunto, porque que quando usamos o operador de type casting (), o compilador não reclama da ausência do ponto e virgula, mas quando retiramos o operado () ele pede o ponto e virgula?
Das duas maneiras funcionaram e imprimiram hadouken na tela =D
E
entanglement
Aqui não há nenhum operador de casting. Basicamente você está definindo uma classe anônima, que implementa ou estende Bar, criando um objeto dessa classe, e então chamando seu método go. Onde está o operador de casting?
Ramundodavy
Sr sethbra…
Estou me referindo a sintaxe de classes anônimas ex:
Portanto, ela segue as mesmas regras que uma expressão do tipo (3 + 4). Em particular, se ela for a última coisa em uma linha, deve ter um “;” depois.
Ramundodavy
Senhores, me perdoem pela confusao, irei colocar o cenário em fóco:
publicclassFoo{Foo(){System.out.print("foo");}classBar{Bar(){System.out.print("bar");}publicvoidgo(){System.out.print("hi");}}publicstaticvoidmain(String[]args){Foof=newFoo();f.makeBar();}voidmakeBar(){//new Bar(){};//Funciona, Classe Interna anonina, Sub-Tipo de Bar(newBar(){}).go();//Amigos, aqui depois da Chaves, nao deveria haver um Ponto e VirgulanewBar(){}.go();//Alguem poderia me explicar porque isso funciona?}}
Meu compilador tá fincando bilé por causa das linhas 21 e 22
M
mspereira
Quanto aos parênteses:
O operador ‘.’ (ponto) é um operador infixo, ou seja, ele fica entre dois operandos.
Como new Bar() {}é o único operador a ser resolvido os parênteses tornam-se opcionais.
Então (new Bar() {}).go();é a mesma coisa que ((((new Bar() {})))).go();, porém new Bar() {}.(go()); ou (new Bar() {}).(go());não compilarão.
É parecido com int a, b=2, c=3;
a = ((((b)))) + c;
a = b + c;
Quanto ao ; (ponto e vírgula):
O ponto-e-vírgula deve ir ao fim de uma instrução.
Seria a mesma coisa de tentar escrever as instruções (que compilam e produzem o mesmo resultado, ainda bem!)new ClasseQualquer01().new ClasseQualquer02().metodoA();
(new ClasseQualquer01()).new ClasseQualquer02().metodoA();
(new ClasseQualquer01().new ClasseQualquer02()).metodoA();
(((new ClasseQualquer01().new ClasseQualquer02()))).metodoA();
da seguinte forma (que não compilará):new ClasseQualquer01();.new ClasseQualquer02().metodoA();
Esse exercício faz parecer que está sendo criada uma classe interna local de método (copiei do livro), mas não está. Também confunde com uma classe interna anônima simples (copiei do livro), que é finalizada com um ponto-e-vírgula, mas também não é.
É simplesmente a criação de uma instância de um classe interna e invocação de um método.
Ufa!
Boa sorte!
Ramundodavy
Gostei da explicação, me convenceu. Mas porque o uso abusivo de chaves não dar erro de compilação?
new Bar(){{}{}{}{}{}{}{}{}{}{}{}}.go();// se substituir isso na llina21 e 22, compila!
M
mspereira
Esse monte de chaves são blocos de inicialização.
Todos são executados na criação da instância de Bar().
Coloca um println dentro de um deles (ou de vários, ou de todos) pra ver o que acontece.