Spec-Zone.ru › Kotlin 2
Руководство по совместимости Kotlin 1.5.x Поддержание актуальности языка и Удобные обновления — одни из фундаментальных принципов проектирования языка Kotlin. Первый принцип гласит, что конструкции, препятствующие развитию языка, следует удалять, а второй — что о таком удалении следует заранее сообщать, чтобы упростить перенос кода.
Хотя большинство изменений языка уже были анонсированы в других источниках, например в журналах изменений обновлений или предупреждениях компилятора, в этом документе они собраны вместе, чтобы предоставить полный справочник по миграции с Kotlin 1.4 на Kotlin 1.5.
Основные термины
В этом документе мы рассматриваем несколько видов совместимости:
исходный код : изменение, несовместимое с исходным кодом, не позволяет скомпилировать код, который ранее компилировался без ошибок и предупреждений
двоичная совместимость : два двоичных артефакта считаются двоично совместимыми, если их взаимная замена не приводит к ошибкам загрузки или связывания
поведенческая совместимость : изменение считается несовместимым с точки зрения поведения, если одна и та же программа ведёт себя по-разному до и после его применения
Помните, что эти определения применимы только к чистому Kotlin. Совместимость кода Kotlin с точки зрения других языков (например, Java) выходит за рамки этого документа.
Язык и стандартная библиотека
Запретить оператор spread в сигнатурно-полиморфных вызовах
Задача : KT-35226
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено использовать оператор spread (*) в сигнатурно-полиморфных вызовах
Цикл устаревания :
< 1.5: появится предупреждение для проблемного оператора в месте вызова
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-ProhibitSpreadOnSignaturePolymorphicCall можно использовать для временного возврата к поведению до версии 1.5
Запретить неабстрактные классы, содержащие невидимые для них абстрактные члены (internal/package-private)
Задача : KT-27825
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено создавать неабстрактные классы, содержащие невидимые для них абстрактные члены (internal/package-private)
Цикл устаревания :
< 1.5: появится предупреждение для проблемных классов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-ProhibitInvisibleAbstractMethodsInSuperclasses можно использовать для временного возврата к поведению до версии 1.5
Запретить использовать массивы на основе нереифицированных параметров типа в качестве реифицированных аргументов типа на JVM
Задача : KT-31227
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено использовать массивы на основе нереифицированных параметров типа в качестве реифицированных аргументов типа на JVM
Цикл устаревания :
< 1.5: появится предупреждение для проблемных вызовов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-ProhibitNonReifiedArraysAsReifiedTypeArguments можно использовать для временного возврата к поведению до версии 1.5
Запретить вторичные конструкторы классов enum, не делегирующие вызов первичному конструктору
Задача : KT-35870
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено создавать вторичные конструкторы классов enum, не делегирующие вызов первичному конструктору
Цикл устаревания :
< 1.5: появится предупреждение для проблемных конструкторов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-RequiredPrimaryConstructorDelegationCallInEnums можно использовать для временного возврата к поведению до версии 1.5
Запретить раскрытие анонимных типов из приватных inline-функций
Задача : KT-33917
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено раскрывать анонимные типы из приватных inline-функций
Цикл устаревания :
< 1.5: появится предупреждение для проблемных конструкторов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-ApproximateAnonymousReturnTypesInPrivateInlineFunctions можно использовать для временного возврата к поведению до версии 1.5
Запретить передачу массивов без spread после аргументов с SAM-преобразованием
Задача : KT-35224
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено передавать массивы без spread после аргументов с SAM-преобразованием
Цикл устаревания :
1.3.70: появится предупреждение для проблемных вызовов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-ProhibitVarargAsArrayAfterSamArgument можно использовать для временного возврата к поведению до версии 1.5
Поддержать специальную семантику параметров блока catch с именем в виде подчёркивания
Задача : KT-31567
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будет запрещено обращаться к символу подчёркивания (_), который используется для пропуска имени параметра исключения в блоке catch
Цикл устаревания :
1.4.20: появится предупреждение для проблемных обращений
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-ForbidReferencingToUnderscoreNamedParameterOfCatchBlock можно использовать для временного возврата к поведению до версии 1.5
Изменить стратегию реализации SAM-преобразования: перейти от анонимных классов к invokedynamic
Задача : KT-44912
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : Начиная с Kotlin 1.5 стратегия реализации SAM-преобразования (single abstract method — единственный абстрактный метод) изменится: вместо генерации анонимного класса будет использоваться инструкция JVM invokedynamic
Цикл устаревания :
Задача : KT-48233
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : В Kotlin 1.5 для компилятора Kotlin/JVM по умолчанию используется бэкенд на основе IR . Для более ранних версий языка по умолчанию по-прежнему используется старый бэкенд.
При использовании нового компилятора в Kotlin 1.5 может наблюдаться снижение производительности. Мы работаем над устранением таких проблем.
Цикл устаревания :
< 1.5: по умолчанию используется старый бэкенд JVM
>= 1.5: по умолчанию используется бэкенд на основе IR. Если в Kotlin 1.5 необходимо использовать старый бэкенд, добавьте следующие строки в файл конфигурации проекта, чтобы временно вернуться к поведению до версии 1.5:
В Gradle:
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
kotlinOptions.useOldBackend = true
}
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) {
kotlinOptions.useOldBackend = true
}
В Maven:
<configuration>
<args>
<arg>-Xuse-old-backend</arg>
</args>
</configuration>
Поддержка этого флага будет удалена в одном из будущих выпусков.
Новая сортировка полей в бэкенде на основе JVM IR
Задача : KT-46378
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : Начиная с версии 1.5, Kotlin использует бэкенд на основе IR , который иначе сортирует байт-код JVM: он генерирует поля, объявленные в конструкторе, перед полями, объявленными в теле класса, тогда как старый бэкенд делает наоборот. Новая сортировка может изменить поведение программ, использующих фреймворки сериализации, зависящие от порядка полей, например сериализацию Java.
Цикл устаревания :
< 1.5: по умолчанию используется старый бэкенд JVM. В нём поля, объявленные в теле класса, идут перед полями, объявленными в конструкторе.
>= 1.5: по умолчанию используется новый бэкенд на основе IR. Поля, объявленные в конструкторе, генерируются перед полями, объявленными в теле класса. В качестве временного решения можно переключиться на старый бэкенд в Kotlin 1.5. Для этого добавьте следующие строки в файл конфигурации проекта:
В Gradle:
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
kotlinOptions.useOldBackend = true
}
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) {
kotlinOptions.useOldBackend = true
}
В Maven:
<configuration>
<args>
<arg>-Xuse-old-backend</arg>
</args>
</configuration>
Поддержка этого флага будет удалена в одном из будущих выпусков.
Генерировать проверку на null для делегированных свойств с обобщённым вызовом в выражении-делегате
Задача : KT-44304
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : Начиная с Kotlin 1.5, компилятор Kotlin будет генерировать проверки на null для делегированных свойств с обобщённым вызовом в выражении-делегате
Цикл устаревания :
Задача : KT-45861
Компонент : Ядро языка
Тип несовместимого изменения : исходный код
Краткое описание : В Kotlin 1.5 будут запрещены вызовы вроде contains, indexOf и assertEquals с бессмысленными аргументами, чтобы повысить безопасность типов
Цикл устаревания :
1.4.0: появится предупреждение для проблемных конструкторов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-StrictOnlyInputTypesChecks можно использовать для временного возврата к поведению до версии 1.5
Использовать правильный порядок вычисления аргументов в вызовах с именованным vararg
Задача : KT-17691
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : В Kotlin 1.5 изменится порядок вычисления аргументов в вызовах с именованным vararg
Цикл устаревания :
< 1.5: появится предупреждение для проблемных конструкторов
>= 1.5: это предупреждение станет ошибкой; -XXLanguage:-UseCorrectExecutionOrderForVarargArguments можно использовать для временного возврата к поведению до версии 1.5
Использовать значение параметра по умолчанию в функциональных вызовах с оператором
Задача : KT-42064
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : В Kotlin 1.5 в вызовах с оператором будет использоваться значение параметра по умолчанию
Цикл устаревания :
Создавать пустые обратные прогрессии в циклах for, если обычная прогрессия тоже пуста
Задача : KT-42533
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : В Kotlin 1.5 будут создаваться пустые обратные прогрессии в циклах for, если обычная прогрессия тоже пуста
Цикл устаревания :
Упорядочить преобразования Char в код и Char в цифру
Задача : KT-23451
Компонент : kotlin-stdlib
Тип несовместимого изменения : исходный код
Краткое описание : Начиная с Kotlin 1.5 преобразования Char в числовые типы будут объявлены устаревшими
Цикл устаревания :
Несогласованное сравнение символов без учёта регистра в функциях kotlin.text
Задача : KT-45496
Компонент : kotlin-stdlib
Тип несовместимого изменения : поведенческое
Краткое описание : Начиная с Kotlin 1.5 будет улучшено сравнение Char.equals без учёта регистра: сначала сравниваются заглавные варианты символов, а затем — строчные варианты этих заглавных вариантов (в отличие от строчных вариантов исходных символов)
Цикл устаревания :
Удалить API преобразования регистра с учётом локали по умолчанию
Задача : KT-43023
Компонент : kotlin-stdlib
Тип несовместимого изменения : исходный код
Краткое описание : Начиная с Kotlin 1.5 функции преобразования регистра с учётом локали по умолчанию, такие как String.toUpperCase(), будут объявлены устаревшими
Цикл устаревания :
Постепенно изменить тип возвращаемого значения функций min и max для коллекций на не допускающий null
Задача : KT-38854
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : исходный код
Краткое описание : в версии 1.6 тип возвращаемого значения функций min и max для коллекций станет не допускающим null
Цикл устаревания :
1.4: ввести функции ...OrNull как синонимы и объявить затронутый API устаревшим (подробности см. в задаче)
1.5.0: повысить уровень устаревания затронутого API до ошибки
>=1.6: повторно добавить затронутый API, изменив тип возвращаемого значения на не допускающий null
Повысить уровень устаревания преобразований типов с плавающей точкой в Short и Byte
Задача : KT-30360
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : исходный код
Краткое описание : преобразования типов с плавающей точкой в Short и Byte, объявленные устаревшими в Kotlin 1.4 с уровнем WARNING, начиная с Kotlin 1.5.0 будут вызывать ошибки.
Цикл устаревания :
Не смешивайте несколько вариантов kotlin-test для JVM в одном проекте
Проблема : KT-40225
Компонент : Gradle
Тип несовместимого изменения : поведенческое
Краткое описание : в проекте могли присутствовать несколько взаимоисключающих вариантов kotlin-test для разных тестовых фреймворков, если один из них подключался транзитивной зависимостью. Начиная с версии 1.5.0 Gradle не позволит использовать взаимоисключающие варианты kotlin-test для разных тестовых фреймворков.
Цикл отказа от поддержки :
< 1.5: разрешено использовать несколько взаимоисключающих вариантов kotlin-test для разных тестовых фреймворков
>= 1.5: поведение изменено, Gradle выбрасывает исключение, например: «Невозможно выбрать модуль с конфликтом по возможности...». Возможные решения:
используйте тот же вариант kotlin-test и соответствующий тестовый фреймворк, которые подключает транзитивная зависимость.
найдите другой вариант зависимости, который не подключает транзитивно вариант kotlin-test, чтобы вы могли использовать нужный вам тестовый фреймворк.
найдите другой вариант зависимости, который транзитивно подключает другой вариант kotlin-test, использующий тот же тестовый фреймворк, который вам нужен.
исключите тестовый фреймворк, подключаемый транзитивно. Ниже приведен пример исключения JUnit 4:
configurations {
testImplementation.get().exclude("org.jetbrains.kotlin", "kotlin-test-junit")
}
После исключения тестового фреймворка протестируйте приложение. Если оно перестало работать, отмените внесенные изменения, используйте тот же тестовый фреймворк, что и библиотека, и исключите свой тестовый фреймворк.
26 мая 2025 г.