Ola Bini, um dos responsáveis pelo blog de Java da editora APress comentou sobre as duas propostas para a implementação de closures na linguagem Java e os problemas que cada uma delas pode trazer (ou resolver) caso sejam adicionadas:
Se eu tivesse que escolher, não colocaria nenhuma das duas, não acho que a sintaxe do Java aguente mais uma puxada grande como essa, além do que, a maioria das bibliotecas básicas da linguagem foi escrita sem isso e vai contunuiar funcionando assim.
A turma quente do Java 5 (Neal Gafter, Gilad Bracha, Peter van der Ahé, e honorariamente o James Gosling) postou mais uma versão (simplificada, dessa vez) da proposta para Closures.
Eu ainda sou mais a favor da proposta do Gafter, mas as outras parecem ser mais simples.
Vou postar abaixo um exemplo (que obviamente não compila) do que seria possível com a proposta BGGA (Bracha, Gafter, Gosling, Ahé).
Uma coisa que incomoda no começo, mas a que você se acostuma depois, é que você tem de usar “invoke” explicitamente, em vez de usar uma closure como se fosse um nome de função.
importjava.util.*;classCliente{privateStringnome;privateintid;publicStringgetNome()...blablabla...}classTesteClosures{/** * Function composition, like Haskell's operator "." * f . g (x) is equivalent to f (g (x)) * @param f the first function * @param g the second function * @return An instance of a function that is the composition of f and g. */publicstatic{double=>double}compose({double=>double}f,{double=>double}g){returnnew{double=>double}(){doubleinvoke(doublex){returnf.invoke(g.invoke(x));}}}/** * Sample of "compose" */private{double=>double}sin={doublex=>Math.sin(x);}private{double=>double}sqrt={doublex=>Math.sqrt(x);}private{double=>double}sinsqrt=compose(sin,sqrt);private{double=>double}abscos=compose({x=>Math.abs(x);},{y=>Math.abs(y);});publicstaticvoidmain(String[]args){List<Cliente>clientes=newArrayList<Cliente>();//-- Composição de funções//-- Ordenando com "closures"{Cliente,Cliente=>int}ordemCrescente={Clientec1,Clientec2=>intret=c1.getNome().compareTo(c2.getNome());if(ret!=0)returnret;returnc1.getId()-c2.getId();};{Cliente,Cliente=>int}ordemDecrescente={Clientec1,Clientec2=>return-ordemCrescente.invoke(c1,c2);};// ordem crescenteclientes.sort(ordemCrescente);// ordem decrescenteclientes.sort(ordemDecrescente);//-- Usando um comparator tradicional e inner classes// ordem crescenteclientes.sort(newComparator<Cliente>(){publicintcompare(Clientec1,Clientec2){intret=c1.getNome().compareTo(c2.getNome());if(ret!=0)returnret;returnc1.getId()-c2.getId();}}// ordem decrescenteclientes.sort(newComparator<Cliente>(){publicintcompare(Clientec1,Clientec2){intret=c1.getNome().compareTo(c2.getNome());if(ret!=0)return-ret;returnc2.getId()-c1.getId();}}}}