É uma expressão lambda algo mais do que uma classe interna anônima com um único método?

39

Existe um novo hype com as tão esperadas expressões lambda no Java 8; a cada 3 dias, outro artigo aparece com eles sobre como eles são legais.

Até onde entendi, uma expressão lambda nada mais é do que uma classe interna anônima com um único método (pelo menos no nível de código de bytes). Além disso, ele vem com outro recurso interessante - inferência de tipos, mas acredito que o equivalente a isso possa ser alcançado com genéricos em algum nível (claro que não de uma maneira tão precisa como nas expressões lambda).

Sabendo disso, as expressões lambda vão trazer algo mais do que apenas um sugar sintático em Java? Posso criar classes mais poderosas e flexíveis ou outras construções orientadas a objetos com expressões lambda que não podem ser construídas com recursos de linguagem atuais?

    
por m3th0dman 16.04.2013 / 11:19
fonte

5 respostas

47

tl; dr: enquanto é principalmente açúcar sintático, a sintaxe mais agradável torna muitas coisas práticas que costumavam terminar em linhas infinitas e ilegíveis de chaves e parênteses.

Bem, na verdade é o contrário, pois os lambdas são muito mais antigos que o Java. Classes internas anônimas com um único método são (eram) as mais próximas que Java veio para lambdas. É uma aproximação que foi "boa o suficiente" por algum tempo, mas tem uma sintaxe muito desagradável.

Na superfície, os lambdas do Java 8 parecem não ser muito mais que açúcar sintático, mas quando você olha abaixo da superfície, você 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 fossem objetos, a JVM não precisa implementá-los dessa forma.

Mas apesar de todo esse truque técnico ser interessante e relevante (já que permite futuras otimizações na JVM!), o benefício real é "apenas" a parte sintática do açúcar.

O que é mais fácil de ler:

myCollection.map(new Mapper<String,String>() {
  public String map(String input) {
    return new StringBuilder(input).reverse().toString();
  }
});

ou:

myCollection.map(element -> new StringBuilder(element).reverse().toString());

ou (usando um identificador de método em vez de um lambda):

myCollection.map(String::toUpperCase);

O fato de que você pode finalmente expressar de uma maneira concisa que anteriormente seriam 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).

    
por 16.04.2013 / 11:35
fonte
14

Para Java, sim, nada mais é do que uma maneira melhor de criar uma classe interna anônima. Isto é devido à decisão fundamental em java de que todo bit de código de byte tem que viver dentro de uma classe específica, o que não pode ser alterado agora depois de décadas de código legado a considerar.

No entanto, não é isso que as expressões lambda realmente tratam. Nos formalismos, onde eles são conceitos nativos, em vez de um contorcionismo saltitante, os lambdas são blocos de construção fundamentais; tanto a sua sintaxe como a atitude das pessoas em relação a eles são muito diferentes. O exemplo de uma função anônima recursiva criada exclusivamente 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 o modo de aprender a programar é apenas esotérico para se tornar uma história de sucesso mainstream.)

    
por 16.04.2013 / 12:22
fonte
2

Sim, é apenas um açúcar sintático, no sentido de que em qualquer lugar que você escrever um lambda, você pode reescrever essa expressão como uma expressão de classe interna anônima com um método, onde a classe implementa a interface funcional inferida para o lambda. contexto, 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.

    
por 16.04.2013 / 23:37
fonte
0

Joachim Sauer já fez um bom trabalho respondendo a sua pergunta, mas apenas sugeriu algo que considero importante. Como os Lambdas não são classes, eles também não são compilados 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, usar o Lambdas não apenas torna seu código mais bonito, mas também reduz o tamanho do seu código compilado, o espaço ocupado pela memória do ClassLoader e o tempo necessário para transferir os bits do disco rígido.

    
por 23.06.2016 / 17:12
fonte
-1

Não. Eles não são.

Outra maneira de colocar isso é que os lambdas são uma maneira não-orientada a objeto, porém concisa, de atingir a mesma coisa que uma classe anônima ou, minha preferência, classe interna alcançaria de uma maneira orientada a objeto.

    
por 19.02.2014 / 19:10
fonte