Há um novo hype com as tão esperadas expressões lambda no Java 8; a cada três dias, outro artigo aparece com eles sobre como eles são legais.
Até onde eu entendi, uma expressão lambda nada mais é do que uma classe interna anônima com um único método (pelo menos no nível do código de bytes). Além disso, ele vem com outro recurso interessante - a inferência de tipo, mas acredito que o equivalente a isso possa ser alcançado com genéricos em algum nível (é claro que não de maneira organizada, como nas expressões lambda).
Sabendo disso, as expressões lambda trarão algo mais do que apenas uma adição sintática em Java? Posso criar classes mais poderosas e flexíveis ou outras construções orientadas a objetos com expressões lambda que não são possíveis de serem construídas com os recursos de linguagem atuais?
fonte
this
paraOuterClass.this
faz parte do processo de descodificação de expressões lambda em classe anônima.Respostas:
tl; dr: embora seja principalmente açúcar sintático, essa sintaxe mais agradável torna muitas coisas práticas que costumavam terminar em linhas intermináveis e ilegíveis de chaves e parênteses.
Bem, na verdade é o contrário, já que as lambdas são muito mais antigas que o Java. Classes internas anônimas com um único método são (eram) as Java mais próximas das lambdas. É uma aproximação que foi "boa o suficiente" por algum tempo, mas tem uma sintaxe muito desagradável.
Na superfície, as lambdas do Java 8 parecem não ser muito mais que açúcar sintático, mas quando você olha abaixo da superfície, vê toneladas de abstrações interessantes. Por exemplo, a especificação da JVM trata um lambda de maneira bem diferente de um objeto "true" e, embora você possa manipulá- los como se estivessem onde objetos, a JVM não é obrigada a implementá-los como tal.
Porém, embora todo esse truque técnico seja interessante e relevante (uma vez que permite futuras otimizações na JVM!), O benefício real é "apenas" a parte do açúcar sintático.
O que é mais fácil de ler:
ou:
ou (usando uma alça de método em vez de uma lambda):
O fato de você finalmente poder expressar de forma concisa que anteriormente seria 5 linhas de código (das quais 3 são totalmente chatas) traz uma mudança real do que é prático (mas não do que é possível, concedido).
fonte
List
pode conter qualquer objeto, umList<String>
pode "apenas" segurar seqüências de caracteres. Os genéricos adicionaram uma restrição (e a opção de formalizar restrições!), Não uma adição no poder. Quase tudo desde o Java 1.1 tem sido açúcar sintático. E isso não é necessariamente uma coisa ruim.List<String>
é apenas umList
com conversão paraString
adicionar alguns valores de retorno. No entanto, eles são extremamente úteis e tornaram a linguagem muito mais conveniente para se escrever. Lambdas são casos semelhantes.Para Java, sim, não passa de uma maneira melhor de criar uma classe interna anônima. Isso ocorre devido à decisão fundamental em java de que todo bit de código de bytes precisa viver dentro de uma classe específica, que não pode ser alterada agora após décadas de código legado a considerar.
No entanto, não é sobre isso que as expressões lambda realmente são. Nos formalismos em que são conceitos nativos, em vez de uma contorção de pular corda, as lambdas são blocos de construção fundamentais; a sintaxe e a atitude das pessoas em relação a elas são muito diferentes. O exemplo de uma função recursiva anônima criada puramente a partir de lambdas em Estrutura e interpretação de programas de computador é capaz de mudar toda a sua concepção de computação. (No entanto, tenho certeza de que a maneira de aprender a programar é esotérica para se tornar uma história de sucesso principal).
fonte
Sim, é apenas um açúcar sintático, no sentido de que em qualquer lugar que você escreve um lambda, é possível reescrever essa expressão como uma expressão de classe interna anônima com um método, em que a classe implementa a interface funcional inferida para o contexto do lambda e seria exatamente equivalente semanticamente. E você pode fazer isso simplesmente substituindo a expressão lambda pela expressão de classe anônima, sem alterar nenhuma outra expressão ou linha de código.
fonte
this
precisará ser convertido emOuterClass.this
. Isso não contradiz o que eu disse - toda expressão lambda pode ser convertida em uma expressão de classe anônima semanticamente equivalente sem alterar nada fora dessa expressão . Eu não disse que o interior não mudaria.this
lambda faz parte do açúcar sintático e não faz diferença na semântica. E sobre diferenças na implementação, implementação! = Semântica. Sobre diferenças na identidade do objeto; a identidade do objeto é extremamente tangencial à funcionalidade das lambdas; ninguém verifica a identidade do objeto das classes lambdas / anon de qualquer maneira, porque não é útil.Joachim Sauer já fez um bom trabalho ao responder sua pergunta, mas apenas sugeriu algo que considero importante. Como as Lambdas não são classes, elas também não são compiladas como tal. Todas as classes internas anônimas resultam na criação de um arquivo .class que, por sua vez, deve ser carregado pelo ClassLoader. Portanto, o uso do Lambdas não apenas torna seu código mais bonito, como também reduz o tamanho do código compilado, o espaço de memória do seu ClassLoader e o tempo necessário para transferir os bits do seu disco rígido.
fonte
Não, eles não são.
Outra maneira de dizer isso: as lambdas são uma maneira não-orientada a objetos, por mais concisa que seja, para alcançar a mesma coisa que uma classe anônima ou, minha preferência, classe interna atingiria de maneira orientada a objetos.
fonte