2015-03-19 20 views
24

Na przykład w przypadku anonimowej klasy wewnętrznej przekazywane jest odwołanie do obiektu (anonimowe) i wykonywane są metody tego obiektu.Java Lambdas: jak to działa w JVM i czy jest to OOP?

Lambdy są blokami kodu, które zostaną wykonane w razie potrzeby.

Co dzieje się w JVM podczas napotkania lambdas? Gdzie JVM przechowuje bloki kodu związane z lambdas (Heap: Young, Old lub Permanent Generation)?

Próbowałem wyszukiwania, i mam składnię do używania lambdas, ale nie był w stanie zrozumieć, co dzieje się wewnątrz JVM, jak w JAVA wszystko jest oparte na obiektach.

  1. Więc w kontekście OOP jak działają lambdy?

  2. Czy lambdy naruszają zasady OOP?

  3. Czy Lambda jest dobra dla śmieciarza, ponieważ nie są tworzone żadne przedmioty, stąd nie martwisz się o problemy z pamięcią i czyścisz pamięć?

+0

myślę lambdas są innego sposobu, aby napisać kod bardziej zwarte (albo lepiej). Paradygmat OOP nie jest poruszony w ten sposób, ale to moja opinia. – Rubinum

+0

Lambdas są ważną częścią _funkcjonalnego programowania_, które jest inne, jak wiecie z OOP. – Radek

+0

Na pierwszy rzut oka notacja lambda wydaje się naruszać niektóre zasady "programowania strukturalnego", które jest (rzadko wspominane) podstawą OOP. Nie studiowałem tego wystarczająco blisko, żeby się rozwinąć, a * javac * i tak stał się jednym wielkim niestrukturalnym bałaganem w ciągu ostatnich 10 lat. –

Odpowiedz

15

Nie marnowałbym czasu na myślenie, że wyrażenia lambda pogodowe są naruszeniem zasad OO. Jego celem jest zwiększenie siły języka, a nie pisanie kodu OO, nie widzę jak lambdy mogą naruszać enkapsulację, dziedziczenie czy polimorfizm.

Ten article wyjaśnia jak Java obsługuje wyrażeń lambda:

Co ciekawe o wyrażeń lambda, że ​​z punktu widzenia użytkownika JVM są całkowicie niewidoczne. Nie ma pojęcia, czym jest anonimowa funkcja lub wyrażenie Lambda. Zna tylko kod bajtowy, który jest ściśle określoną specyfikacją OO. Od twórców języka i jego kompilatora zależy praca w obrębie tych ograniczeń w celu tworzenia nowszych, bardziej zaawansowanych elementów językowych.

Biorąc pod uwagę następujący kod:

List names = Arrays.asList("1", "2", "3"); 
Stream lengths = names.stream().map(name -> name.length()); 

... Zaczyna się po prostu przez wprowadzenie nazw var i wywołuje jego metodę .stream(), ale potem robi coś całkiem eleganckie. Zamiast tworzyć nowy obiekt, który będzie owijał funkcję Lambda, używa nowej instrukcji invokeDynamic, która została dodana w języku Java 7, aby dynamicznie powiązać tę stronę wywołania z rzeczywistą funkcją Lambda.

aload_1 //load the names var 

// call its stream() func 
invokeinterface java/util/List.stream:()Ljava/util/stream/Stream; 

//invokeDynamic magic! 
invokedynamiC#0:apply:()Ljava/util/function/Function; 

//call the map() func 
invokeinterface java/util/stream/Stream.map: 
(Ljava/util/function/Function;)Ljava/util/stream/Stream; 

InvokeDynamic jest instrukcją, która została dodana w Javie 7 do JVM mniej rygorystyczne i pozwala dynamicznych języków związać symboli w czasie wykonywania, w porównaniu robi wszystkie powiązania statycznie, gdy kod jest kompilowany przez JVM.

Kod Lambda

aload_0 
invokevirtual java/lang/String.length:() 
invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
areturn 
+1

To nie jest odpowiedź. To "hej, używa invokedynamic, go i google to". –

+2

To w rzeczywistości odpowiedź, dlatego OP przyjął ją. – Maroun

11

wyrażeń lambda nie są tłumaczone na anonymous inner classes, używają invoke dynamic, który został wprowadzony w Javie 7 do wykonania metody funkcjonalnych. Check this out.

Czy naruszają one OOP? Nie sądzę, że powinno ci to zależeć. Lambdas sprawia, że ​​twój kod jest mniej szczegółowy, łatwiejszy do zrozumienia i "łatwiejszy" do paralelizacji. I o to trzeba się troszczyć.

z mózgu Goetz komentarza:

Nie zarabiać pisać programy obiektowe lub programy funkcjonalne, możemy zarabiać pisać programy robocze.

+1

Afaik lambdas są tłumaczone na anonimowe klasy wewnętrzne w * niektórych * przypadkach. Ale dzieje się to w czasie wykonywania przez invokedynamic program ładujący bootstrap, który określa najlepszą strategię obsługi określonej lambda. – the8472

+1

@ the8472 W niewielkim stopniu, że to stwierdzenie może być widoczne jako poprawne w znaczeniu aniołów na głowie, to nadal jest to pomocna charakterystyka. Znacznie lepiej odrzucić połączenie z klasami wewnętrznymi - doprowadzi to do lepszego zrozumienia. –

+0

@ BrianGoetz, tak naprawdę nie miała to być charakterystyka lambd, więcej szczegółów na temat szczegółów implementacji. – the8472

4
  • wyrażenie lambda jest skompilowany przy użyciu invokedynamic kodu bajtowego.
  • Implementacja Lambda jest przechowywana w tym samym pliku klasy, co specjalna prywatna metoda.
  • To, czy obiekt zostanie utworzony w celu wywołania lambda, zależy od sytuacji. W przypadkach trywialnych lambda jest tłumaczona na ciągły uchwyt metody.
  • Aby utworzyć instancję lambda HotSpot tworzy anonimową klasę, która implementuje funkcjonalny interfejs lambda. Ta klasa nie należy do żadnej ClassLoader.

Zobacz more details od specyfikacji specyfikacji Lambda Expressions JSR.