Domanda

Lamdbaj consente la definizione di chiusure in linguaggio Java, si possono trovare vari esempi qui

La mia domanda riguarda i meccanismi Java sottostanti utilizzati, ad esempio, per definire la chiusura println , viene utilizzato il seguente codice:

Closure println = closure(); 
{ of(System.out).println(var(String.class)); }

Questa chiusura può essere successivamente eseguita tramite:

println.apply("foobar");

Sono curioso di sapere quali meccanismi in Java permetterebbero alla chiamata di di (...). println (...) di associarsi al println istanza stessa.

Naturalmente, il codice sorgente lambdaj è disponibile per la lettura, ma speravo in una spiegazione di livello leggermente superiore se qualcuno ne avesse uno. Le mie capacità di riflessione vanno fino a un po 'di introspezione ed esecuzione di metodi dinamici.

È stato utile?

Soluzione

Bene, di è presumibilmente un metodo statico che viene importato staticamente in modo che possa essere chiamato senza il nome della classe che lo racchiude. Mi aspetto che var sia lo stesso. Entrambi i metodi devono restituire un tipo con i metodi successivamente chiamati:

public class Printable {
  public void println(Var var);
}

public class Fac {
  public static Printable of(Object o) {
    return new Printable(o);
  }

  public static Var var(Class<?> clazz) {
    return new Var(clazz);
  }

} 

Improvvisamente:

Fac.of(System.out).println(Fac.var(String.class));

Java valido. Utilizzando le importazioni statiche, hey presto:

import static Fac.*;

of(System.out).println(var(String.class));

Le parentesi graffe sono ovviamente Java valide in quanto è possibile aggiungerle in qualsiasi metodo per aiutare a definire un sope lessicale. Questo stile di progettazione API si chiama fluente ed è presentato al meglio da la JMock libreria di test.

A proposito, se si suppone che ciò introduca chiusure a Java, è abbastanza ridicolo - la sintassi è illeggibilmente orribile . Il loro esempio di I / O mi ha fatto ridere a crepapelle. Prova Scala !

MODIFICA - le due chiamate println sono associate credo perché la prima sequenza di chiamate consente alla libreria di acquisire le variabili che sono state passate come parametri. Questi sono probabilmente catturati in una struttura ThreadLocal . Quando chiami quindi un metodo (anche presumibilmente statico) println , la libreria utilizza questi dati acquisiti per eseguire effettivamente il comportamento in un secondo momento. Anche relativo ai test, il framework di test EasyMock utilizza un meccanismo simile (che utilizza proxy Java in background) per acquisire i valori previsti.

Altri suggerimenti

Sono Mario Fusco e sono lo sviluppatore principale della libreria lambdaj.

Prima di tutto vorrei chiarire qualcosa: lambdaj non intende sostituire alcun linguaggio funzionale. Come ho detto la scorsa settimana nel mio discorso alla Brocca di Zurigo se hai la possibilità di usare la Scala, provaci e non guardare mai indietro. Qui puoi trovare un riassunto del mio intervento in cui si afferma chiaramente che:

http://ctpjava.blogspot.com/ 2009/10 / lambdaj-nuove-trend-in-java.html

Anche io sono un felice sviluppatore di Scala. Ma a volte sei solo obbligato a sviluppare in Java (nella mia esperienza, nel mondo reale, circa l'80% delle volte che non puoi scegliere in quale lingua devi scrivere il tuo codice) e in questo caso alcune delle funzionalità lambdaj potrebbero essere utile (o lo spero). Volevo solo portare a Java alcune funzionalità funzionali che mancano totalmente. Ovviamente il risultato non è del tutto soddisfacente principalmente a causa della limitazione imposta da Java stesso.

Per quanto riguarda il meccanismo interno lambdaj, sì, utilizza un ThreadLocal per ottenere quel risultato. Se hai altre domande, curiosità o suggerimenti ancora migliori e critiche costruttive su lambdaj, potresti essere interessato a registrarti alla mailing list lambdaj qui:

http://groups.google.com/group/lambdaj

Bye Mario

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top