Na czym opierają się wyrażenia lambda?
sobes.tech AI
Odpowiedź od AI
Oparty na mechanizmie Invoke Dynamic (JSR 292). Pozwala odłożyć rozwiązywanie wywołań metod do momentu wykonania. To sprawia, że lambdy są bardziej elastyczne i wydajne niż użycie anonimowych klas wewnętrznych dla prostych interfejsów funkcyjnych.
Kompilator Java przekształca wyrażenie lambda w specyficzną konstrukcję korzystającą z metody statycznej lambda$(), wywoływanej przez invokedynamic.
Przykład:
// Interfejs funkcyjny
interface MyFunctionalInterface {
void myMethod();
}
// Użycie lambdy
public class LambdaExample {
public static void main(String[] args) {
MyFunctionalInterface myLambda = () -> System.out.println("Witaj z lambdy!");
myLambda.myMethod();
}
}
Po kompilacji kod z lambdą będzie wyglądał mniej więcej tak (w bajtkodzie):
invokedynamic #0:myMethod:()V()LI; // BootstrapMethod:lambda$0
astore_1
aload_1
invokeinterface MyFunctionalInterface.myMethod:()V interface 1
Metoda bootstrap (metoda inicjująca ładowanie) dla invokedynamic decyduje, którą metodę wywołać. W przypadku lambd, zazwyczaj jest to java.lang.invoke.LambdaMetafactory.metafactory(), która generuje klasę i instancję interfejsu funkcyjnego w czasie wykonywania, łącząc ją z implementacją lambdy (w tym przypadku, statyczną metodą lambda$0).
To podejście zmniejsza koszty tworzenia wielu anonimowych klas wewnętrznych dla prostych lambd, poprawiając wydajność i zużycie pamięci, szczególnie w kolekcjach i strumieniach.