278 подписчиков
Я нечасто ковыряюсь в байткоде, так как стараюсь не напрягать и без того опухающую от объёма информации голову, но недавнее открытие меня заставило заглянуть в байткод и удивиться.
До появления лямбда-выражений в Java 8 достаточно часто в коде можно было встретить использование анонимных классов, которые во многих случаях были заменены как раз лямбда выражениями. И я всё это время думал, что лямбды - это синтаксический сахар вокруг всё тех же анонимных классов. Но, копаясь в class-файлах одного проекта, я обратил внимание на отсутствие анонимного класса там, где он по моим соображениям должен был находиться.
Каково же было моё удивление, когда в байткоде класса, в котором применялось лямбда-выражение, я обнаружил статический метод с сигнатурой лямбда выражения...
Короче, лямбда-выражение в Java - это упрощенная запись статического метода, используемого по ссылке.
Если мы имеем такой код:
class SomeClass {
private BiFunction<Integer, Integer, Integer> adder = (a, b) -> a + b;
}
То в байткоде он будет выглядеть следующим образом:
class SomeClass {
private BiFunction<Integer, Integer, Integer> adder = SomeClass::add;
public static Integer add(Integer a, Integer b) {
return a + b;
}
}
* Хотя правильнее с исходном варианте заменить лямбду на Integer::sum
В целом весьма изящное решение. Примерно так же компилируются функции в Scala.
#java #байткод #лямбда
1 минута
29 мая 2023