Поиск…


Вступление

Android поддерживает все языковые функции Java 7 и набор функций языка Java 8, которые различаются по версии платформы. На этой странице описываются новые возможности языка, которые вы можете использовать, как правильно настроить проект для их использования и любые известные проблемы, с которыми вы можете столкнуться.

Java 8 имеет подмножество с Retrolambda

Retrolambda позволяет запускать код Java 8 с помощью лямбда-выражений, ссылок на методы и операторов try-with-resources на Java 7, 6 или 5. Это делается путем преобразования вашего скомпилированного байт-кода Java 8, чтобы он мог работать в более старой среде выполнения Java.

Особенности языка бэкпорта:

  • Лямбда-выражения передаются обратно, превращая их в анонимные внутренние классы. Это включает в себя оптимизацию использования экземпляра singleton для выражений лямбда без учета состояния, чтобы избежать повторного распределения объектов. Ссылки на методы - это, по сути, только синтаксический сахар для лямбда-выражений, и они обращаются таким же образом.

  • Операторы Try-with-resources передаются обратно, удаляя вызовы Throwable.addSuppressed если целевая версия байт-кода находится ниже Java 7. Если вы хотите, чтобы исключенные исключения были записаны вместо проглатывания, создайте запрос функции, и мы сделаем это настраивается.

  • Objects.requireNonNull вызовы заменяются вызовами Object.getClass если целевая версия байт-кода находится ниже Java 7. Синтетические проверки на null, сгенерированные JDK 9, используют Objects.requireNonNull , тогда как в предыдущих версиях JDK использовался Object.getClass .

  • Дополнительно также:

    1. Способы по умолчанию возвращаются путем копирования методов по умолчанию в класс сопутствующего класса (имя интерфейса + «$») в качестве статических методов, заменяя методы по умолчанию в интерфейсе абстрактными методами и добавляя необходимые реализации методов ко всем классам, реализующим этот интерфейс ,

    2. Статические методы на интерфейсах возвращаются путем перемещения статических методов в класс компаньона (имя интерфейса + «$») и путем изменения всех вызовов методов для вызова нового расположения метода.

Известные ограничения:

  • Не поддерживает API-интерфейсы Java 8

  • Backporting методы по умолчанию и статические методы на интерфейсах требуют, чтобы все backported интерфейсы и все классы, которые их реализовали, или вызывали их статические методы для резервного копирования вместе с одним выполнением Retrolambda. Другими словами, вы всегда должны делать чистую сборку. Кроме того, методы backporting default не будут работать через границы модулей или зависимостей.

  • Может разорваться, если будущая сборка JDK 8 перестанет генерировать новый класс для каждого invokedynamic вызова. Retrolambda работает так, что он захватывает байт-код, который java.lang.invoke.LambdaMetafactory генерируется динамически, поэтому оптимизация этого механизма может сломать Retrolambda.

Retrolambda gradle plugin автоматически создаст ваш проект Android с Retrolambda. Последнюю версию можно найти на странице выпусков .

Использование:

  1. Загрузите и установите jdk8
  2. Добавьте в свой build.gradle
buildscript {
  repositories {
     mavenCentral()
  }

  dependencies {
     classpath 'me.tatarka:gradle-retrolambda:<latest version>'
  }
}

// Required because retrolambda is on maven central
repositories {
  mavenCentral()
}

apply plugin: 'com.android.application' //or apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Известные вопросы:

  • Lint терпит неудачу в java-файлах, которые имеют lambdas. Волокна Android не понимает синтаксис java 8 и терпит неудачу молча или громко. В настоящее время существует экспериментальная версия, которая устраняет проблему.

  • Использование служб Google Play приводит к сбою Retrolambda. Версия 5.0.77 содержит байт-код, который несовместим с Retrolambda. Это должно быть исправлено в новых версиях игровых сервисов, если вы можете их обновить, это должно быть предпочтительным решением. Чтобы обойти эту проблему, вы можете использовать более раннюю версию, например 4.4.52, или добавить -noverify в jvm args.

retrolambda {
  jvmArgs '-noverify'
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow