Cierre en Java 7 [cerrado]


105

¿Qué es el cierre? Se supone que está incluido en Java 7. (Se discutió la inclusión de cierres en Java 7, pero al final no se incluyeron. -Ed) ¿Alguien puede proporcionarme algunas referencias fiables de las que pueda aprender cosas sobre cierres?

Respuestas:


59

Aquí está el blog de Neal Gafter, uno de los pioneros en introducir cierres en Java. Su publicación sobre cierres del 28 de enero de 2007 se llama Definición de cierres. En su blog hay mucha información para empezar, así como videos. Aquí hay una excelente charla de Google - Temas avanzados en lenguajes de programación - Cierres para Java con Neal Gafter, también.


2
¿Tiene un enlace más específico que el blog en general?
I82Much


1
Si alguien es tonto como yo y te golpeas la cabeza contra la pared solo para saber qué diablos es este cierre ... entonces aquí tienes ... youtube.com/watch?v=Nj3_DMUXEbE
Piyush Kukadiya

No puedo imaginar la implementación de cierres en un lenguaje que inicialmente no los tenía ... kinda loco
Alexander Mills

Alexander Mills solo tiene curiosidad ... ¿por qué?
Bartzilla

84

Un cierre es un bloque de código al que se puede hacer referencia (y pasar) con acceso a las variables del ámbito adjunto.

Desde Java 1.1, la clase interna anónima ha proporcionado esta función de una manera muy detallada. También tienen la restricción de poder usar solo finalvariables locales (y definitivamente asignadas). (Tenga en cuenta que incluso finallas variables no locales están dentro del alcance, pero no se pueden usar).

Java SE 8 está destinado a tener una versión más concisa de esto para interfaces de método único *, llamadas "lambdas". Las lambdas tienen las mismas restricciones que las clases internas anónimas, aunque algunos detalles varían aleatoriamente.

Las lambdas se están desarrollando en el marco del Proyecto Lambda y JSR 335 .

* Originalmente, el diseño era más flexible y permitía tipos de métodos abstractos únicos (SAM). Desafortunadamente, el nuevo diseño es menos flexible, pero intenta justificar la implementación dentro de las interfaces.


7

Según Tom Hawtin

Un cierre es un bloque de código al que se puede hacer referencia (y pasar) con acceso a las variables del ámbito adjunto.

Ahora estoy tratando de emular el ejemplo de cierre de JavaScript en Wikipedia , con una traducción " directa " a Java, con la esperanza de que sea útil:

//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"

Ahora la parte de Java: Function1 es la interfaz "Functor" con arity 1 (un argumento). Closure es la clase que implementa Function1, un Functor concreto que actúa como función (int -> int). En el método main (), simplemente instancia foo como un objeto Closure, replicando las llamadas del ejemplo de JavaScript. La clase IntBox es solo un contenedor simple, se comporta como una matriz 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());

    }
}

Imprime:

inside foo, call to f.apply(): 2
call to foo.g.apply(): 1
call to foo.f.apply(): 2 

2
En mi opinión, además del nombre, esto no tiene nada que ver con los cierres
n00b


4

Java Closures formará parte de J2SE 8 y está previsto que se publique a finales de 2012.

El soporte de cierres de Java 8 incluye el concepto de expresiones Lambda, referencia de método, referencia de constructor y métodos predeterminados.

Para obtener más información y ejemplos prácticos para esto, visite: http://amitrp.blogspot.in/2012/08/at-first-sight-with-closures-in-java.html


1
Hmm, sin embargo, Java 8 no permite la modificación de la variable de cierre. Buen artículo.
nawfal


0

Una implementación de cierre para Java 5, 6 y 7

http://mseifed.blogspot.se/2012/09/bringing-closures-to-java-5-6-and-7.html

Contiene todo lo que uno podría pedir ...


El vínculo va a un texto que lo describe, pero el código vinculado desde esa página no existe. ¿Dónde está la implementación?
Jerry Jeremiah

@JerryJeremiah Aquí está, tiene un nombre diferente ahora, también todas las versiones originalmente presentes no están allí (para admitir acceso no final y más a través de clases abstractas, podría agregarse nuevamente para <versiones de Java 8, ¿qué plataforma eres? buscando?): bitbucket.org/momomo/opensource/src
mmm

2
¡Los enlaces se rompen!
sunleo

tengo un 404 el enlace está muerto
Alexander Mills

enlace roto (es por eso que no debemos poner enlaces como respuestas ...)
OhadR
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.