Zamknięcie w Javie 7 [zamknięte]

105

Co to jest zamknięcie? Powinien być zawarty w Javie 7. (Zamknięcia zostały omówione do włączenia do Javy 7, ale ostatecznie nie zostały uwzględnione. -Ed) Czy ktoś może mi podać jakieś wiarygodne referencje, z których mogę dowiedzieć się czegoś o domknięciach?

Swaranga Sarma
źródło

Odpowiedzi:

59

Oto blog Neala Gaftera, jednego z pionierów wprowadzających zamknięcia w Javie. Jego post dotyczący zamknięć z 28 stycznia 2007 r. Nosi tytuł Definicja zamknięć. Na jego blogu znajduje się wiele informacji, które pomogą Ci zacząć, a także filmy. Oto doskonała rozmowa Google - Zaawansowane tematy w językach programowania - Zamknięcia języka Java z Neal Gafter.

Bartzilla
źródło
2
Czy masz bardziej szczegółowy link niż ogólny blog?
I82 Dużo
1
Jeśli ktoś jest taki głupi jak ja i jeśli
bijesz
Nie mogę sobie wyobrazić implementacji domknięć w języku, w którym początkowo ich nie było… trochę szalone
Alexander Mills
Alexander Mills jest po prostu ciekawy ... dlaczego?
Bartzilla
84

Zamknięcie to blok kodu, do którego można się odwoływać (i przekazywać go) z dostępem do zmiennych z otaczającego zakresu.

Od wersji Java 1.1 anonimowe klasy wewnętrzne udostępniały tę funkcję w bardzo rozwlekły sposób. Mają również ograniczenie możliwości używania final(i definitywnie przypisanych) zmiennych lokalnych. (Uwaga, nawet finalzmienne inne niż lokalne znajdują się w zakresie, ale nie można ich używać).

Java SE 8 ma mieć bardziej zwięzłą wersję tego dla interfejsów jednometodowych *, zwanych „lambdami”. Lambdy mają takie same ograniczenia jak anonimowe klasy wewnętrzne, chociaż niektóre szczegóły różnią się losowo.

Lambdy są opracowywane w ramach Projektu Lambda i JSR 335 .

* Pierwotnie projekt był bardziej elastyczny, pozwalając na typy pojedynczych metod abstrakcyjnych (SAM). Niestety nowy projekt jest mniej elastyczny, ale próbuje usprawiedliwić dopuszczenie do implementacji w ramach interfejsów.

Tom Hawtin - haczyk
źródło
7

Według Toma Hawtina

Zamknięcie to blok kodu, do którego można się odwoływać (i przekazywać go) z dostępem do zmiennych z otaczającego zakresu.

Teraz próbuję emulować przykład zamknięcia JavaScript w Wikipedii , z „ prostym ” tłumaczeniem na Javę, w nadziei, że będzie to przydatne:

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

Teraz część java: Function1 to interfejs "Functor" z wartością 1 (jeden argument). Closure to klasa implementująca Function1, konkretny Funktor, który działa jako funkcja (int -> int). W metodzie main () po prostu tworzę instancję foo jako obiekt Closure, replikując wywołania z przykładu JavaScript. Klasa IntBox jest po prostu prostym kontenerem, zachowuje się jak tablica 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());

    }
}

Drukuje:

inside foo, call to f.apply(): 2
call to foo.g.apply(): 1
call to foo.f.apply(): 2 
Rob Rosetti
źródło
2
IMO poza nazwą nie ma to nic wspólnego z zamknięciami
n00b
4

Java Closures będzie częścią J2SE 8 i ma zostać wydane do końca 2012 roku.

Obsługa zamknięć Java 8 obejmuje koncepcję wyrażeń lambda, odwołania do metod, odniesienia do konstruktora i metod domyślnych.

Więcej informacji i przykłady robocze można znaleźć na stronie : http://amitrp.blogspot.in/2012/08/at-first-sight-with-closures-in-java.html

Amit Phaltankar
źródło
1
Hmm, jednak Java 8 nie pozwala na modyfikację zmiennej zamknięcia. Dobry artykuł.
nawfal
0

Implementacja zamknięcia dla Java 5, 6 i 7

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

Zawiera wszystko, o co można prosić ...

mmm
źródło
Odsyłacz prowadzi do tekstu go opisującego, ale kod, do którego prowadzi łącze z tej strony, nie istnieje. Gdzie jest wdrożenie?
Jerry Jeremiah
@JerryJeremiah Tutaj jest, ma teraz inną nazwę, również nie ma tam wszystkich wersji oryginalnie obecnych (aby wspierać dostęp nie ostateczny, a więcej poprzez klasy abstrakcyjne, można go dodać ponownie dla wersji <Java 8, na jakiej jesteś platformie szukasz?): bitbucket.org/momomo/opensource/src
mmm
2
Linki się zrywają!
sunleo
mam 404, link nie działa
Alexander Mills,
link uszkodzony (dlatego nie powinniśmy umieszczać linków jako odpowiedzi ...)
OhadR