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?

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.


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.


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 

2
IMO poza nazwą nie ma to nic wspólnego z zamknięciami
— n00b




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ć ...


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.