Según Tom Hawtin
Une fermeture est un bloc de code qui peut être référencé (et auquel on peut passer autour) avec un accès aux variables de la portée englobante.
Maintenant, j'essaie d'émuler l'exemple de fermeture JavaScript sur Wikipedia avec un " droiture " en Java, dans l'espoir d'être utile :
//ECMAScript
var f, g;
function foo() {
var x = 0;
f = function() { return ++x; };
g = function() { return --x; };
x = 1;
print('inside foo, call to f(): ' + f()); // "2"
}
foo();
print('call to g(): ' + g()); // "1"
print('call to f(): ' + f()); // "2"
Maintenant la partie java : Function1 est une interface "Functor" d'arité 1 (un argument). Closure est la classe qui implémente Function1, un Functor concret qui agit comme une fonction (int -> int). Dans la méthode main(), j'instancie simplement foo en tant qu'objet Closure, reproduisant les appels de l'exemple JavaScript. La classe IntBox est juste un simple conteneur, elle se comporte comme un tableau de 1 int :
int a\[1\] = {0}
interface Function1 {
public final IntBag value = new IntBag();
public int apply();
}
class Closure implements Function1 {
private IntBag x = value;
Function1 f;
Function1 g;
@Override
public int apply() {
// print('inside foo, call to f(): ' + f()); // "2"
// inside apply, call to f.apply()
System.out.println("inside foo, call to f.apply(): " + f.apply());
return 0;
}
public Closure() {
f = new Function1() {
@Override
public int apply() {
x.add(1);
return x.get();
}
};
g = new Function1() {
@Override
public int apply() {
x.add(-1);
return x.get();
}
};
// x = 1;
x.set(1);
}
}
public class ClosureTest {
public static void main(String[] args) {
// foo()
Closure foo = new Closure();
foo.apply();
// print('call to g(): ' + g()); // "1"
System.out.println("call to foo.g.apply(): " + foo.g.apply());
// print('call to f(): ' + f()); // "2"
System.out.println("call to foo.f.apply(): " + foo.f.apply());
}
}
Il imprime :
inside foo, call to f.apply(): 2
call to foo.g.apply(): 1
call to foo.f.apply(): 2