Spec-Zone.ru › Kotlin 2

Что нового в Kotlin 1.4.30

Выпущено: 3 февраля 2021 г.

В Kotlin 1.4.30 представлены предварительные версии новых языковых возможностей, новая IR-архитектура бэкенда компилятора Kotlin/JVM получила статус бета-версии, а также были внесены различные улучшения производительности и функциональности.

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

Информацию о цикле выпуска Kotlin см. в разделе Процесс выпуска Kotlin.

Языковые возможности

В Kotlin 1.5.0 появятся новые языковые возможности: поддержка JVM-записей, sealed-интерфейсы и стабильные inline-классы. В Kotlin 1.4.30 вы можете попробовать эти возможности и улучшения в предварительном режиме. Будем очень признательны, если вы поделитесь с нами отзывами в соответствующих задачах YouTrack: это позволит нам учесть их до выпуска 1.5.0.

  • Поддержка JVM-записей

  • Sealed-интерфейсы и улучшения sealed-классов

  • Улучшенные inline-классы

Чтобы включить эти языковые возможности и улучшения в предварительном режиме, необходимо добавить определенные параметры компилятора. Подробности см. в разделах ниже.

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

Поддержка JVM-записей

Возможность работы с JVM-записями является экспериментальной. Она может быть удалена или изменена в любое время. Требуется явное согласие на использование (см. подробности ниже); эту возможность следует использовать только для оценки. Будем признательны за ваши отзывы в YouTrack.

Выпуск JDK 16 предполагает стабилизацию нового типа классов Java под названием record. Чтобы предоставить все преимущества Kotlin и сохранить совместимость с Java, Kotlin вводит экспериментальную поддержку классов-записей.

Классы-записи, объявленные в Java, можно использовать в Kotlin так же, как классы со свойствами. Дополнительные действия не требуются.

Начиная с версии 1.4.30, можно объявить класс-запись в Kotlin, используя аннотацию @JvmRecord для класса данных:

@JvmRecord
data class User(val name: String, val age: Int)

Чтобы попробовать предварительную версию JVM-записей, добавьте параметры компилятора -Xjvm-enable-preview и -language-version 1.5.

Мы продолжаем работу над поддержкой JVM-записей и будем очень признательны, если вы поделитесь с нами отзывами в этой задаче YouTrack.

Подробнее о реализации, ограничениях и синтаксисе см. в KEEP.

Sealed-интерфейсы

Sealed-интерфейсы являются экспериментальными. Они могут быть удалены или изменены в любое время. Требуется явное согласие на использование (см. подробности ниже); использовать их следует только для оценки. Будем признательны за ваши отзывы в YouTrack.

В Kotlin 1.4.30 мы представляем прототип sealed-интерфейсов. Они дополняют sealed-классы и позволяют создавать более гибкие ограниченные иерархии классов.

Они могут выступать в роли «внутренних» интерфейсов, которые нельзя реализовать за пределами того же модуля. Например, это позволяет полагаться на данный факт при написании исчерпывающих выражений when.

sealed interface Polygon

class Rectangle(): Polygon
class Triangle(): Polygon

// when() is exhaustive: no other polygon implementations can appear
// after the module is compiled
fun draw(polygon: Polygon) = when (polygon) {
    is Rectangle -> // ...
    is Triangle -> // ...
}

Еще один вариант использования: с sealed-интерфейсами можно наследовать класс от двух или более sealed-суперклассов.

sealed interface Fillable {
   fun fill()
}
sealed interface Polygon {
   val vertices: List<Point>
}

class Rectangle(override val vertices: List<Point>): Fillable, Polygon {
   override fun fill() { /*...*/ }
}

Чтобы попробовать предварительную версию sealed-интерфейсов, добавьте параметр компилятора -language-version 1.5. После этого вы сможете использовать модификатор sealed для интерфейсов. Будем очень признательны, если вы поделитесь с нами отзывами в этой задаче YouTrack.

Подробнее о sealed-интерфейсах.

Иерархии sealed-классов в пределах пакета

Иерархии sealed-классов в пределах пакета являются экспериментальными. Они могут быть удалены или изменены в любое время. Требуется явное согласие на использование (см. подробности ниже); использовать их следует только для оценки. Будем признательны за ваши отзывы в YouTrack.

Теперь sealed-классы могут образовывать более гибкие иерархии. Их подклассы могут находиться во всех файлах одной единицы компиляции и одного пакета. Ранее все подклассы должны были находиться в одном файле.

Прямые подклассы могут быть верхнеуровневыми или вложенными в любое количество других именованных классов, именованных интерфейсов или именованных объектов. Подклассы sealed-класса должны иметь полностью квалифицированное имя — они не могут быть локальными или анонимными объектами.

Чтобы попробовать иерархии sealed-классов в пределах пакета, добавьте параметр компилятора -language-version 1.5. Будем очень признательны, если вы поделитесь с нами отзывами в этой задаче YouTrack.

Подробнее об иерархиях sealed-классов в пределах пакета.

Улучшенные inline-классы

Inline-классы-значения находятся в статусе бета-версии. Они почти стабильны, но в будущем могут потребоваться шаги по миграции. Мы приложим все усилия, чтобы свести к минимуму необходимые изменения. Будем признательны за ваши отзывы о возможности использования inline-классов в YouTrack.

В Kotlin 1.4.30 inline-классы получили статус бета-версии, а также следующие возможности и улучшения:

  • Поскольку inline-классы основаны на значениях, их можно объявлять с помощью модификатора value. Модификаторы inline и value теперь эквивалентны. В будущих версиях Kotlin мы планируем объявить модификатор inline устаревшим.

    Теперь для бэкенда JVM перед объявлением класса Kotlin требует аннотацию @JvmInline:

    inline class Name(private val s: String)
    
    value class Name(private val s: String)
    
    // For JVM backends
    @JvmInline
    value class Name(private val s: String)
    
  • В inline-классах могут быть блоки init. В них можно добавить код, который будет выполнен сразу после создания экземпляра класса:

    @JvmInline
    value class Negative(val x: Int) {
      init {
          require(x < 0) { }
      }
    }
    
  • Вызов функций с inline-классами из кода Java: до Kotlin 1.4.30 из-за модификации имен вы не могли вызывать из Java функции, принимающие inline-классы. Теперь модификацию имен можно отключить вручную. Чтобы вызывать такие функции из кода Java, добавьте аннотацию @JvmName перед объявлением функции:

    inline class UInt(val x: Int)
    
    fun compute(x: Int) { }
    
    @JvmName("computeUInt")
    fun compute(x: UInt) { }
    
  • В этом выпуске мы изменили схему модификации имен функций, чтобы исправить некорректное поведение. Эти изменения привели к изменениям ABI.

    Начиная с версии 1.4.30 компилятор Kotlin по умолчанию использует новую схему модификации имен. Используйте флаг компилятора -Xuse-14-inline-classes-mangling-scheme, чтобы заставить компилятор использовать старую схему модификации имен из версии 1.4.0 и сохранить двоичную совместимость.

В Kotlin 1.4.30 inline-классы получили статус бета-версии, и в будущих выпусках мы планируем присвоить им статус стабильных. Будем очень признательны, если вы поделитесь с нами отзывами в этой задаче YouTrack.

Чтобы попробовать предварительную версию inline-классов, добавьте параметр компилятора -Xinline-classes или -language-version 1.5.

Подробнее об алгоритме модификации имен см. в KEEP.

Подробнее об inline-классах.

Kotlin/JVM

IR-бэкенд компилятора JVM получил статус бета-версии

Бэкенд компилятора на основе IR для Kotlin/JVM, представленный в версии 1.4.0 в статусе альфа-версии, получил статус бета-версии. Это последний этап перед стабилизацией, после которого IR-бэкенд станет используемым по умолчанию для компилятора Kotlin/JVM.

Теперь снято ограничение на использование бинарных файлов, созданных IR-компилятором. Ранее код, скомпилированный новым бэкендом JVM IR, можно было использовать только при включенном новом бэкенде. Начиная с версии 1.4.30 такого ограничения нет, поэтому новый бэкенд можно использовать для сборки компонентов для сторонних пользователей, например библиотек. Попробуйте бета-версию нового бэкенда и поделитесь отзывами в нашем трекере задач.

Чтобы включить новый бэкенд JVM IR, добавьте следующие строки в файл конфигурации проекта:

  • В Gradle:

    tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile::class) {
      kotlinOptions.useIR = true
    }
    
    tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile) {
      kotlinOptions.useIR = true
    }
    
  • В Maven:

    <configuration>
        <args>
            <arg>-Xuse-ir</arg>
        </args>
    </configuration>
    

Подробнее об изменениях, привнесенных бэкендом JVM IR, читайте в этой записи в блоге.

Kotlin/Native

Повышение производительности

В Kotlin/Native в версии 1.4.30 внесено множество улучшений производительности, благодаря которым сократилось время компиляции. Например, время, необходимое для повторной сборки фреймворка в примере «Сетевое взаимодействие и хранение данных с Kotlin Multiplatform Mobile», сократилось с 9,5 секунды (в версии 1.4.10) до 4,5 секунды (в версии 1.4.30).

Целевая платформа 64-разрядного симулятора Apple watchOS

Целевая платформа симулятора x86 устарела для watchOS начиная с версии 7.0. Чтобы поддерживать последние версии watchOS, в Kotlin/Native появилась новая целевая платформа watchosX64 для запуска симулятора на 64-разрядной архитектуре.

Поддержка библиотек Xcode 12.2

Мы добавили поддержку новых библиотек, поставляемых с Xcode 12.2. Теперь их можно использовать в коде Kotlin.

Kotlin/JS

Ленивая инициализация свойств верхнего уровня

Ленивая инициализация свойств верхнего уровня является экспериментальной. Она может быть удалена или изменена в любое время. Требуется явное согласие на использование (см. подробности ниже); эту возможность следует использовать только для оценки. Будем признательны за ваши отзывы в YouTrack.

Для IR-бэкенда Kotlin/JS реализован прототип ленивой инициализации свойств верхнего уровня. Это уменьшает необходимость инициализировать все свойства верхнего уровня при запуске приложения и должно значительно сократить время запуска.

Мы продолжим работу над ленивой инициализацией и просим вас попробовать текущий прототип и поделиться своими мнениями и результатами в этой задаче YouTrack или в канале #javascript официального Slack-сообщества Kotlin (получить приглашение можно здесь).

Чтобы использовать ленивую инициализацию, добавьте параметр компилятора -Xir-property-lazy-initialization при компиляции кода компилятором JS IR.

Улучшения проектов Gradle

Поддержка кэша конфигурации Gradle

Начиная с версии 1.4.30 плагин Kotlin Gradle поддерживает функцию кэша конфигурации. Она ускоряет процесс сборки: после запуска команды Gradle выполняет этап конфигурации и вычисляет граф задач. Gradle сохраняет результат в кэше и использует его при последующих сборках.

Чтобы начать использовать эту возможность, можно воспользоваться командой Gradle или настроить IDE на основе IntelliJ.

Стандартная библиотека

API преобразования текста в верхний и нижний регистр без учета локали

API, не зависящий от локали, является экспериментальным. Он может быть удален или изменен в любое время. Используйте его только для оценки. Будем признательны за ваши отзывы в YouTrack.

В этом выпуске представлен экспериментальный API, не зависящий от локали, для изменения регистра строк и символов. Текущие функции API toLowerCase(), toUpperCase(), capitalize(), decapitalize() зависят от локали. Это означает, что настройки локали разных платформ могут влиять на поведение кода. Например, в турецкой локали при преобразовании строки "kotlin" с помощью toUpperCase получается "KOTLİN", а не "KOTLIN".

// current API
println("Needs to be capitalized".toUpperCase()) // NEEDS TO BE CAPITALIZED

// new API
println("Needs to be capitalized".uppercase()) // NEEDS TO BE CAPITALIZED

В Kotlin 1.4.30 доступны следующие альтернативы:

  • Для функций String:

    Предыдущие версии

    Альтернатива в версии 1.4.30

    String.toUpperCase()

    String.uppercase()

    String.toLowerCase()

    String.lowercase()

    String.capitalize()

    String.replaceFirstChar { it.uppercase() }

    String.decapitalize()

    String.replaceFirstChar { it.lowercase() }

  • Для функций Char:

    Предыдущие версии

    Альтернатива в версии 1.4.30

    Char.toUpperCase()

    Char.uppercaseChar(): Char
    Char.uppercase(): String

    Char.toLowerCase()

    Char.lowercaseChar(): Char
    Char.lowercase(): String

    Char.toTitleCase()

    Char.titlecaseChar(): Char
    Char.titlecase(): String

Для Kotlin/JVM также существуют перегруженные функции uppercase(), lowercase() и titlecase() с явным параметром Locale.

Полный список изменений функций обработки текста см. в KEEP.

Однозначные преобразования Char в код и Char в цифру

Однозначный API для преобразования Char является экспериментальным. Он может быть удален или изменен в любое время. Используйте его только для оценки. Будем признательны за ваши отзывы в YouTrack.

Текущие функции преобразования Char в числа, которые возвращают коды UTF-16 в различных числовых типах, часто путают с похожим преобразованием String в Int, которое возвращает числовое значение строки:

"4".toInt() // returns 4
'4'.toInt() // returns 52
// and there was no common function that would return the numeric value 4 for Char '4'

Чтобы избежать путаницы, мы решили разделить преобразования Char на два набора функций с понятными названиями:

  • Функции для получения целочисленного кода Char и создания Char по заданному коду:

    fun Char(code: Int): Char
    fun Char(code: UShort): Char
    val Char.code: Int
    
  • Функции для преобразования Char в числовое значение представляемой ею цифры:

    fun Char.digitToInt(radix: Int): Int
    fun Char.digitToIntOrNull(radix: Int): Int?
    
  • Функция расширения для Int, преобразующая представляемую ею неотрицательную однозначную цифру в соответствующее представление Char:

    fun Int.digitToChar(radix: Int): Char
    

Подробнее см. в KEEP.

Обновления сериализации

Вместе с Kotlin 1.4.30 мы выпускаем kotlinx.serialization 1.1.0-RC, включающую несколько новых возможностей:

  • Поддержка сериализации inline-классов

  • Поддержка сериализации беззнаковых примитивных типов

Поддержка сериализации inline-классов

Начиная с Kotlin 1.4.30, inline-классы можно сделать сериализуемыми:

@Serializable
inline class Color(val rgb: Int)

Для этой возможности требуется новый компилятор IR версии 1.4.30.

Среда сериализации не упаковывает сериализуемые inline-классы, когда они используются в других сериализуемых классах.

Подробнее см. в kotlinx.serialization документации.

Поддержка сериализации беззнаковых примитивных типов

Начиная с версии 1.4.30, для беззнаковых примитивных типов можно использовать стандартные сериализаторы JSON из kotlinx.serialization: UInt, ULong, UByte и UShort:

@Serializable
class Counter(val counted: UByte, val description: String)
fun main() {
   val counted = 239.toUByte()
   println(Json.encodeToString(Counter(counted, "tries")))
}

Подробнее см. в kotlinx.serialization документации.

15 января 2026
Руководство по совместимости для Kotlin 1.5.xЧто нового в Kotlin 1.4.20

© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew1430.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API