Лямбда-выражения бэкпортированы в Java 7, 6 и 5

http://blog.orfjackal.net/2013/07/lambda-expressions-backported-to-java-7.html
  • Перевод

Хотите использовать лямбда-выражения, но вынуждены использовать стабильный JRE? Теперь это возможно с утилитой Retrolambda, которая преобразует байткод Java 8 в пригодный для рантаймов Java 7, 6 и 5, позволяя использовать лямбда-выражения и ссылки на методы на этих платформах. Конечно, придется отказаться от улучшенного Java 8 Collections API, но, к счастью, существует множество альтернативных библиотек, работа с которыми упростится благодаря лямбда-выражениям.

Под капотом


Пару дней назад в кафе мне в голову пришла идея поискать кого-нибудь, кто уже занимался этой проблемой, но после пары разговоров со стенкой, сделал все самостоятельно за выходные.

Изначальный план тупого копирования классов из OpenJDK провалился (LambdaMetafactory зависит от некоторых приватных классов и требовала модификации), но в конечном итоге я нашел путь избежать лишних зависимостей от рантайма.

Retrolambda использует Java аgent для поиска байткода, который динамически генерируется LambdaMetafactory, сохранения его как .class-файла и замены инструкций invokedynamic на явную инициализацию этих классов. Библиотека также меняет модификатор видимости некоторых синтетических методов на package, таким образом байткод может получить к ним доступ без использования MethodHandle.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 12
  • 0
    Прикольно. Может кто уже попробовал, как оно?
    • +6
      Вах, круто. Надо испытать на dalvik vm — будет ли работать… Очень вкусно выглядит.
      • +1
        Ну если оно шаманит с байткодом — то работать скорее всего не будет. Но проверить все же надо. Может манипуляции с байткодом выполняются на стороне JVM, до конвертации в байткод dalvik.
        • 0
          Да, там модифицируется немного байткод и добавляется пара классов, результат проверки чуть ниже.
        • +3
          Виии, работает!
          public class Test {
          	public static void main(String[] args) {
          		System.out.println("=== Runnable test on Dalvik VM ===");
          		Runnable r1 = new Runnable() {
          			@Override
          			public void run() {
          				System.out.println("First runnable");
          			}
          		};
          		Runnable r2 = () -> { System.out.println("Second runnable"); };
          		
          		r1.run(); r2.run();
          	}
          }
          

          javac Test.java
          java -Dretrolambda.inputDir=. -Dretrolambda.classpath=. -Dretrolambda.bytecodeVersion=50 -javaagent:retrolambda.jar -jar retrolambda.jar
          zip package.jar *.class
          java -jar /opt/android-sdk/build-tools/17.0.0/lib/dx.jar --dex --output=package-dx.jar package.jar
          adb push package-dx.jar /sdcard/package-dx.jar
          adb shell
          su -c ash
          dalvikvm -classpath /sdcard/package-dx.jar Test
          

          • +2
            именно эта ссылка и указана в источнике перевода
          • +5
            Чего только не придумают, лишь бы на Scala не писать.
            • +4
              Какие тока Scala не придумают, лишь бы на Java не писать.
              • –2
                Что только не придумают, чтобы не писать.
            • +2
              Странное желание использовать стабильный JRE и нестабильную библиотеку. Lambda до сих пор в бете.
              • 0
                Бета — не альфа, перепишем, если что :)

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.