Найти в Дзене

Я нечасто ковыряюсь в байткоде, так как стараюсь не напрягать и без того опухающую от объёма информации голову, но недавнее открытие меня заставило заглянуть в байткод и удивиться.


До появления лямбда-выражений в 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 минута