Spec-Zone.ru › Kotlin 2
Руководство по совместимости с Kotlin 1.3.x Поддержание актуальности языка и Удобство обновлений — одни из фундаментальных принципов проектирования языка Kotlin. Первый гласит, что конструкции, препятствующие развитию языка, следует удалять, а второй — что об этом удалении следует заблаговременно сообщать, чтобы перенос кода проходил как можно более гладко.
Хотя большинство изменений языка уже были объявлены через другие каналы, например в журналах изменений обновлений или предупреждениях компилятора, в этом документе они собраны вместе, чтобы предоставить полное руководство по переходу с Kotlin 1.2 на Kotlin 1.3.
Основные термины
В этом документе рассматриваются несколько видов совместимости:
Исходная : изменение, нарушающее исходную совместимость, не позволяет скомпилировать код, который раньше успешно компилировался (без ошибок или предупреждений)
Бинарная : два бинарных артефакта считаются бинарно-совместимыми, если их взаимная замена не приводит к ошибкам загрузки или связывания
Поведенческая : изменение считается нарушающим поведенческую совместимость, если одна и та же программа ведёт себя по-разному до и после его применения
Помните, что эти определения относятся только к чистому Kotlin. Совместимость кода Kotlin с точки зрения других языков (например, Java) выходит за рамки этого документа.
Несовместимые изменения
Порядок вычисления аргументов конструктора относительно вызова <clinit>
Проблема : KT-19532
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : в версии 1.3 изменился порядок вычисления относительно инициализации класса
Цикл устаревания :
<1.3: старое поведение (подробности см. в описании проблемы)
>= 1.3: поведение изменено, -Xnormalize-constructor-calls=disable можно использовать для временного возврата к поведению до версии 1.3. Поддержка этого флага будет удалена в следующем основном выпуске.
Отсутствие аннотаций с целевым элементом getter у параметров конструктора аннотации
Проблема : KT-25287
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : в версии 1.3 аннотации с целевым элементом getter у параметров конструктора аннотации будут корректно записываться в файлы классов
Цикл устаревания :
<1.3: аннотации с целевым элементом getter у параметров конструктора аннотации не применяются
>=1.3: аннотации с целевым элементом getter у параметров конструктора аннотации корректно применяются и записываются в сгенерированный код
Отсутствующие ошибки в аннотациях @get: конструктора класса
Проблема : KT-19628
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : в версии 1.3 ошибки в аннотациях с целевым элементом getter будут корректно сообщаться
Цикл устаревания :
<1.2: об ошибках компиляции в аннотациях с целевым элементом getter не сообщалось, поэтому некорректный код успешно компилировался.
1.2.x: об ошибках сообщают только инструменты; компилятор по-прежнему компилирует такой код без предупреждений
>=1.3: компилятор тоже сообщает об ошибках, отклоняя ошибочный код
Проверки на null при обращении к типам Java, аннотированным @NotNull
Проблема : KT-20830
Компонент : Kotlin/JVM
Тип несовместимого изменения : поведенческое
Краткое описание : проверки на null для типов Java, аннотированных аннотациями not-null, будут генерироваться активнее, из-за чего код, передающий сюда null, будет быстрее завершаться с ошибкой.
Цикл устаревания :
<1.3: при выводе типов компилятор мог пропускать такие проверки, что позволяло потенциально распространять null при компиляции с использованием двоичных файлов (подробности см. в описании проблемы).
>=1.3: компилятор генерирует пропущенные проверки. Из-за этого код, который (ошибочно) пропускал здесь nulls, будет быстрее завершаться с ошибкой. -XXLanguage:-StrictJavaNullabilityAssertions можно использовать для временного возврата к поведению до версии 1.3. Поддержка этого флага будет удалена в следующем основном выпуске.
Ненадёжные смарткасты для элементов перечисления
Проблема : KT-20772
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : смарткаст для члена одной записи перечисления будет применяться только к этой записи
Цикл устаревания :
<1.3: смарткаст члена одной записи перечисления мог приводить к ненадёжному смарткасту того же члена в других записях перечисления.
>=1.3: смарткаст будет корректно применяться только к члену одной записи перечисления. -XXLanguage:-SoundSmartcastForEnumEntries временно вернёт старое поведение. Поддержка этого флага будет удалена в следующем основном выпуске.
Повторное присваивание резервного поля val в getter
Проблема : KT-16681
Компоненты : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : повторное присваивание резервному полю свойства val в его getter теперь запрещено
Цикл устаревания :
<1.2: компилятор Kotlin разрешал изменять резервное поле val в его getter. Это не только нарушает семантику Kotlin, но и генерирует некорректный байт-код JVM, повторно присваивающий поле final.
1.2.X: для кода, повторно присваивающего резервное поле val, выдаётся предупреждение об устаревании
>=1.3: предупреждения об устаревании повышены до ошибок
Фиксация массива перед циклом for, в котором он перебирается
Проблема : KT-21354
Компонент : Kotlin/JVM
Тип несовместимого изменения : исходный код
Краткое описание : если выражение в диапазоне цикла for — локальная переменная, обновляемая в теле цикла, это изменение влияет на выполнение цикла. Такое поведение отличается от перебора других контейнеров, например диапазонов, последовательностей символов и коллекций.
Цикл устаревания :
<1.2: описанные шаблоны кода успешно компилируются, но изменения локальной переменной влияют на выполнение цикла
1.2.X: предупреждение об устаревании выдаётся, если выражение диапазона в цикле for — локальная переменная типа массива, которой присваивается значение в теле цикла
1.3: в таких случаях поведение изменено для соответствия поведению других контейнеров
Вложенные классификаторы в записях перечисления
Проблема : KT-16310
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3, вложенные классификаторы (классы, объекты, интерфейсы, классы-аннотации и классы-перечисления) в записях перечисления запрещены
Цикл устаревания :
<1.2: вложенные классификаторы в записях перечисления успешно компилируются, но во время выполнения могут привести к исключению
1.2.X: для вложенных классификаторов выдаются предупреждения об устаревании
>=1.3: предупреждения об устаревании повышены до ошибок
Переопределение copy в классе данных
Проблема : KT-19618
Компоненты : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3, классам данных запрещено переопределять copy()
Цикл устаревания :
<1.2: классы данных, переопределяющие copy(), успешно компилируются, но могут завершиться ошибкой во время выполнения или демонстрировать странное поведение
1.2.X: для классов данных, переопределяющих copy(), выдаются предупреждения об устаревании
>=1.3: предупреждения об устаревании повышены до ошибок
Внутренние классы, наследующие Throwable и захватывающие обобщённые параметры внешнего класса
Проблема : KT-17981
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 внутренним классам запрещено наследовать Throwable
Цикл устаревания :
<1.2: внутренние классы, наследующие Throwable, успешно компилируются. Если такие внутренние классы захватывают обобщённые параметры, это может привести к странным шаблонам кода, которые завершаются ошибкой во время выполнения.
1.2.X: для внутренних классов, наследующих Throwable, выдаются предупреждения об устаревании
>=1.3: предупреждения об устаревании повышены до ошибок
Правила видимости в сложных иерархиях классов с companion-объектами
Проблемы : KT-21515 , KT-25333
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 правила видимости по кратким именам становятся строже для сложных иерархий классов с companion-объектами и вложенными классификаторами.
Цикл устаревания :
<1.2: старые правила видимости (подробности см. в описании проблемы)
1.2.X: для кратких имён, которые больше не будут доступны, выдаются предупреждения об устаревании. Инструменты предлагают автоматическую миграцию с добавлением полного имени.
>=1.3: предупреждения об устаревании повышены до ошибок. В проблемном коде следует добавить полные квалификаторы или явные импорты
Неконстантные параметры vararg аннотаций
Проблема : KT-23153
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 передача неконстантных значений в качестве параметров vararg аннотации запрещена
Цикл устаревания :
<1.2: компилятор разрешает передавать неконстантное значение параметру vararg аннотации, но фактически отбрасывает это значение при генерации байт-кода, что приводит к неочевидному поведению
1.2.X: для таких шаблонов кода выдаются предупреждения об устаревании
>=1.3: предупреждения об устаревании повышены до ошибок
Локальные классы-аннотации
Проблема : KT-23277
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 локальные классы-аннотации не поддерживаются
Цикл устаревания :
<1.2: компилятор успешно компилировал локальные классы-аннотации
1.2.X: для локальных классов-аннотаций выдаются предупреждения об устаревании
>=1.3: предупреждения об устаревании повышены до ошибок
Смарткасты для локальных делегированных свойств
Проблема : KT-22517
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 смарткасты для локальных делегированных свойств запрещены
Цикл устаревания :
<1.2: компилятор разрешал выполнять смарткаст локального делегированного свойства, что могло приводить к ненадёжному смарткасту при некорректно работающих делегатах
1.2.X: смарткасты локальных делегированных свойств помечаются как устаревшие (компилятор выдаёт предупреждения)
>=1.3: предупреждения об устаревании повышены до ошибок
Соглашение об операторе mod
Проблемы : KT-24197
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 объявление оператора mod запрещено, как и вызовы, разрешающиеся в такие объявления
Цикл устаревания :
1.1.X, 1.2.X: выдаются предупреждения для объявлений operator mod, а также для вызовов, разрешающихся в него
1.3.X: предупреждения повышены до ошибок, но разрешение в объявления operator mod по-прежнему допускается
1.4.X: вызовы больше не разрешаются в operator mod
Проблемы : KT-20588 , KT-20589 . См. также KT-20171
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : в Kotlin 1.3 присваивание одного элемента параметру vararg считается устаревшим и должно быть заменено последовательным использованием spread и созданием массива.
Цикл устаревания :
<1.2: присваивание одного значения параметру vararg в именованной форме успешно компилируется и рассматривается как присваивание одного элемента массиву, что приводит к неочевидному поведению при присваивании массива параметру vararg
1.2.X: для таких присваиваний выдаются предупреждения об устаревании; пользователям предлагается перейти на последовательное использование spread и создание массива.
1.3.X: предупреждения повышены до ошибок
>= 1.4: изменена семантика присваивания одного элемента параметру vararg: присваивание массива становится эквивалентно присваиванию массива с оператором spread
Сохранение аннотаций с целью EXPRESSION
Проблема : KT-13762
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 для аннотаций с целью EXPRESSION разрешено только сохранение SOURCE
Цикл устаревания :
<1.2: аннотации с целью EXPRESSION и сохранением, отличным от SOURCE, разрешены, но молча игнорируются в местах использования
1.2.X: для объявлений таких аннотаций выдаются предупреждения об устаревании
>=1.3: предупреждения повышены до ошибок
Аннотации с целью PARAMETER не должны применяться к типу параметра
Проблема : KT-9580
Компонент : Основной язык
Тип несовместимого изменения : исходный код
Краткое описание : начиная с Kotlin 1.3 ошибка о неверной цели аннотации будет корректно сообщаться, если аннотация с целью PARAMETER применена к типу параметра
Цикл устаревания :
<1.2: описанные выше шаблоны кода успешно компилируются; аннотации молча игнорируются и отсутствуют в байт-коде
1.2.X: при таком использовании выдаются предупреждения об устаревании
>=1.3: предупреждения повышены до ошибок
Array.copyOfRange выбрасывает исключение, если индексы выходят за границы, вместо увеличения возвращаемого массива
Проблема : KT-19489
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : поведенческое
Краткое описание : начиная с Kotlin 1.3 проверяется, что аргумент toIndex функции Array.copyOfRange, обозначающий исключительную конечную границу копируемого диапазона, не превышает размер массива; если превышает, выбрасывается IllegalArgumentException.
Цикл устаревания :
<1.3: если toIndex при вызове Array.copyOfRange превышает размер массива, недостающие элементы диапазона заполняются значениями null, что нарушает надёжность системы типов Kotlin.
>=1.3: проверяется, что toIndex находится в пределах границ массива; в противном случае выбрасывается исключение
Прогрессии Int и Long с шагом Int.MIN_VALUE и Long.MIN_VALUE запрещены и не могут быть созданы
Проблема : KT-17176
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : поведенческое
Краткое описание : начиная с Kotlin 1.3 запрещено задавать для целочисленных прогрессий в качестве шага минимальное отрицательное значение соответствующего целочисленного типа (Long или Int), поэтому вызов IntProgression.fromClosedRange(0, 1, step = Int.MIN_VALUE) будет выбрасывать IllegalArgumentException
Цикл устаревания :
<1.3: можно было создать IntProgression с шагом Int.MIN_VALUE, дающую два значения [0, -2147483648], что приводило к неочевидному поведению
>=1.3: если шаг равен минимальному отрицательному значению соответствующего целочисленного типа, выбрасывается IllegalArgumentException
Проверка переполнения индекса при операциях с очень длинными последовательностями
Проблема : KT-16097
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : Поведенческое
Краткое описание : начиная с Kotlin 1.3 гарантируется, что методы index, count и подобные не вызывают переполнения при работе с длинными последовательностями. Полный список затронутых методов см. в описании проблемы.
Цикл устаревания :
<1.3: вызов таких методов для очень длинных последовательностей мог приводить к отрицательным результатам из-за переполнения целого числа
>=1.3: обнаружение переполнения в таких методах и немедленное выбрасывание исключения
Проблема : KT-21049
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : Поведенческое
Краткое описание : начиная с Kotlin 1.3 поведение метода split при разделении по регулярному выражению с пустым совпадением унифицировано на всех платформах
Цикл устаревания :
<1.3: поведение описанных вызовов различается в JS, JRE 6 и JRE 7 по сравнению с JRE 8+
>=1.3: поведение унифицировано на всех платформах
Удаление устаревших артефактов из дистрибутива компилятора
Проблема : KT-23799
Компонент : прочее
Тип несовместимого изменения : Бинарное
Краткое описание : в Kotlin 1.3 прекращается поставка следующих устаревших бинарных артефактов:
kotlin-runtime: используйте вместо него kotlin-stdlib
kotlin-stdlib-jre7/8: используйте вместо него kotlin-stdlib-jdk7/8
kotlin-jslib в дистрибутиве компилятора: используйте вместо него kotlin-stdlib-js
Цикл устаревания :
1.2.X: артефакты были помечены как устаревшие, компилятор выдавал предупреждение при их использовании
>=1.3: поставка артефактов прекращена
Аннотации в стандартной библиотеке
Проблема : KT-21784
Компонент : kotlin-stdlib (JVM)
Тип несовместимого изменения : Бинарное
Краткое описание : в Kotlin 1.3 аннотации из пакета org.jetbrains.annotations удаляются из стандартной библиотеки и переносятся в отдельные артефакты, поставляемые вместе с компилятором: annotations-13.0.jar и mutability-annotations-compat.jar
Цикл устаревания :
26 мая 2025 г.