Spec-Zone.ru › Kotlin 2

Что нового в Kotlin 1.5.30

Выпущен: 24 августа 2021 г.

В Kotlin 1.5.30 представлены обновления языка, включая предварительные версии будущих изменений, различные улучшения поддержки платформ и инструментов, а также новые функции стандартной библиотеки.

Вот некоторые важные улучшения:

  • Возможности языка, включая экспериментальные инструкции sealed when, изменения в использовании требований opt-in и другие

  • Поддержка Apple silicon

  • Бэкенд Kotlin/JS IR достиг стадии Beta

  • Улучшения работы с плагином Gradle

Краткий обзор изменений также представлен в публикации о выпуске и в этом видео:

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

Возможности языка

В Kotlin 1.5.30 представлены предварительные версии будущих изменений языка, а также улучшения механизма требований opt-in и вывода типов:

  • Полные инструкции when для субъектов sealed и Boolean

  • Функции-приостановки в качестве супертипов

  • Требование opt-in для неявного использования экспериментальных API

  • Изменения в использовании аннотаций требований opt-in с разными целями

  • Улучшения вывода типов для рекурсивных обобщённых типов

  • Снятие ограничений на вывод типов в конструкторах

Полные инструкции when для субъектов sealed и Boolean

Поддержка полных инструкций when для sealed является экспериментальной. Она может быть удалена или изменена в любое время. Требуется opt-in (подробности см. ниже); используйте эту возможность только для оценки. Мы будем признательны за ваш отзыв в YouTrack.

Полная инструкция when содержит ветви для всех возможных типов или значений своего субъекта либо для определённых типов и ветвь else, охватывающую все оставшиеся случаи.

В ближайшее время мы планируем запретить неполные инструкции when, чтобы их поведение соответствовало выражениям when. Для обеспечения плавного перехода можно настроить компилятор так, чтобы он выдавал предупреждения о неполных инструкциях when с sealed-классом или Boolean. По умолчанию такие предупреждения появятся в Kotlin 1.6, а позднее станут ошибками.

Для enum-перечислений предупреждение уже выдаётся.

sealed class Mode {
    object ON : Mode()
    object OFF : Mode()
}

fun main() {
    val x: Mode = Mode.ON
    when (x) { 
        Mode.ON -> println("ON")
    }
// WARNING: Non exhaustive 'when' statements on sealed classes/interfaces 
// will be prohibited in 1.7, add an 'OFF' or 'else' branch instead

    val y: Boolean = true
    when (y) {  
        true -> println("true")
    }
// WARNING: Non exhaustive 'when' statements on Booleans will be prohibited 
// in 1.7, add a 'false' or 'else' branch instead
}

Чтобы включить эту возможность в Kotlin 1.5.30, используйте версию языка 1.6. Также можно преобразовать предупреждения в ошибки, включив прогрессивный режим.

kotlin {
    sourceSets.all {
        languageSettings.apply {
            languageVersion = "1.6"
            //progressiveMode = true // false by default
        }
    }
}
kotlin {
    sourceSets.all {
        languageSettings {
            languageVersion = '1.6'
            //progressiveMode = true // false by default
        }
    }
}

Функции-приостановки в качестве супертипов

Поддержка функций-приостановок в качестве супертипов является экспериментальной. Она может быть удалена или изменена в любое время. Требуется opt-in (подробности см. ниже); используйте эту возможность только для оценки. Мы будем признательны за ваш отзыв в YouTrack.

В Kotlin 1.5.30 представлена предварительная версия возможности использовать функциональный тип suspend в качестве супертипа с некоторыми ограничениями.

class MyClass: suspend () -> Unit {
    override suspend fun invoke() { TODO() }
}

Чтобы включить эту возможность, используйте параметр компилятора -language-version 1.6:

kotlin {
    sourceSets.all {
        languageSettings.apply {
            languageVersion = "1.6"
        }
    }
}
kotlin {
    sourceSets.all {
        languageSettings {
            languageVersion = '1.6'
        }
    }
}

У этой возможности есть следующие ограничения:

  • Нельзя смешивать обычный функциональный тип и функциональный тип suspend в качестве супертипов. Это связано с особенностями реализации функциональных типов suspend в бэкенде JVM. Они представляются в нём как обычные функциональные типы с интерфейсом-маркером. Из-за интерфейса-маркера невозможно определить, какие супер-интерфейсы являются приостанавливающими, а какие — обычными.

  • Нельзя использовать несколько функциональных супертипов suspend. Если выполняются проверки типов, также нельзя использовать несколько обычных функциональных супертипов.

Требование opt-in для неявного использования экспериментальных API

Механизм требований opt-in является экспериментальным. Он может измениться в любое время. Узнайте, как выполнить opt-in. Используйте его только для оценки. Мы будем признательны за ваш отзыв в YouTrack.

Автор библиотеки может пометить экспериментальный API как требующий opt-in, чтобы сообщить пользователям о его экспериментальном статусе. Компилятор выдаёт предупреждение или ошибку при использовании такого API и требует явного согласия, чтобы подавить его.

В Kotlin 1.5.30 компилятор считает экспериментальным любое объявление, в сигнатуре которого используется экспериментальный тип. То есть opt-in требуется даже для неявного использования экспериментального API. Например, если тип возвращаемого значения функции помечен как элемент экспериментального API, для использования этой функции требуется выполнить opt-in, даже если само объявление явно не помечено как требующее opt-in.

// Library code

@RequiresOptIn(message = "This API is experimental.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS)
annotation class MyDateTime // Opt-in requirement annotation

@MyDateTime
class DateProvider // A class requiring opt-in

// Client code

// Warning: experimental API usage
fun createDateSource(): DateProvider { /* ... */ }

fun getDate(): Date {
    val dateSource = createDateSource() // Also warning: experimental API usage
    // ... 
}

Подробнее см. в разделе Требования opt-in.

Изменения в использовании аннотаций требований opt-in с разными целями

Механизм требований opt-in является экспериментальным. Он может измениться в любое время. Узнайте, как выполнить opt-in. Используйте его только для оценки. Мы будем признательны за ваш отзыв в YouTrack.

В Kotlin 1.5.30 представлены новые правила использования и объявления аннотаций требований opt-in с разными целями. Теперь компилятор сообщает об ошибке в случаях, обработка которых во время компиляции нецелесообразна. В Kotlin 1.5.30:

  • Запрещено помечать локальные переменные и параметры-значения аннотациями требований opt-in в месте использования.

  • Переопределение разрешено помечать только в том случае, если помечено и его базовое объявление.

  • Запрещено помечать поля для хранения и геттеры. Вместо этого можно пометить само базовое свойство.

  • Запрещено задавать цели аннотаций TYPE и TYPE_PARAMETER в месте объявления аннотации требования opt-in.

Подробнее см. в разделе Требования opt-in.

Улучшения вывода типов для рекурсивных обобщённых типов

В Kotlin и Java можно определить рекурсивный обобщённый тип, который ссылается на себя в своих параметрах типа. В Kotlin 1.5.30 компилятор Kotlin может вывести аргумент типа, опираясь только на верхние границы соответствующего параметра типа, если он является рекурсивным обобщённым типом. Это позволяет создавать различные шаблоны с рекурсивными обобщёнными типами, которые часто используются в Java для построения API-конструкторов.

// Kotlin 1.5.20
val containerA = PostgreSQLContainer<Nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
    withDatabaseName("db")
    withUsername("user")
    withPassword("password")
    withInitScript("sql/schema.sql")
}

// Kotlin 1.5.30
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
    .withDatabaseName("db")
    .withUsername("user")
    .withPassword("password")
    .withInitScript("sql/schema.sql")

Улучшения можно включить с помощью параметра компилятора -Xself-upper-bound-inference или -language-version 1.6. Другие примеры новых поддерживаемых сценариев использования см. в этой задаче YouTrack.

Снятие ограничений на вывод типов в конструкторах

Вывод типов в конструкторах — это особый вид вывода типов, который позволяет выводить аргументы типа вызова на основе информации о типах из других вызовов внутри его лямбда-аргумента. Это может быть полезно при вызове обобщённых функций-конструкторов, таких как buildList() или sequence(): buildList { add("string") }.

Ранее внутри такого лямбда-аргумента действовало ограничение на использование информации о типах, которую пытается вывести механизм вывода типов в конструкторах. Это означает, что тип можно было только указать, но нельзя было получить. Например, внутри лямбда-аргумента buildList() нельзя было вызвать get() без явного указания аргументов типа.

В Kotlin 1.5.30 эти ограничения снимаются с помощью параметра компилятора -Xunrestricted-builder-inference. Добавьте этот параметр, чтобы разрешить ранее запрещённые вызовы внутри лямбда-аргумента обобщённых функций-конструкторов:

@kotlin.ExperimentalStdlibApi
val list = buildList {
    add("a")
    add("b")
    set(1, null)
    val x = get(1)
    if (x != null) {
        removeAt(1)
    }
}

@kotlin.ExperimentalStdlibApi
val map = buildMap {
    put("a", 1)
    put("b", 1.1)
    put("c", 2f)
}

Эту возможность также можно включить с помощью параметра компилятора -language-version 1.6.

Kotlin/JVM

В Kotlin 1.5.30 для Kotlin/JVM доступны следующие возможности:

  • Создание экземпляров классов аннотаций

  • Улучшенная настройка поддержки аннотаций nullability

Обновления плагина Kotlin Gradle для платформы JVM см. в разделе Gradle.

Создание экземпляров классов аннотаций

Создание экземпляров классов аннотаций является экспериментальным. Эта возможность может быть удалена или изменена в любое время. Требуется opt-in (подробности см. ниже); используйте эту возможность только для оценки. Мы будем признательны за ваш отзыв в YouTrack.

Начиная с Kotlin 1.5.30, можно вызывать конструкторы классов аннотаций в произвольном коде, чтобы получить экземпляр. Эта возможность охватывает те же сценарии использования, что и соглашение Java, позволяющее реализовывать интерфейс аннотации.

annotation class InfoMarker(val info: String)

fun processInfo(marker: InfoMarker) = ...

fun main(args: Array<String>) {
    if (args.size != 0)
        processInfo(getAnnotationReflective(args))
    else
        processInfo(InfoMarker("default"))
}

Чтобы включить эту возможность, используйте параметр компилятора -language-version 1.6. Обратите внимание, что все существующие ограничения классов аннотаций остаются в силе, например запрет на объявление параметров, отличных от val, или членов, отличных от вторичных конструкторов.

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

Улучшенная настройка поддержки аннотаций nullability

Компилятор Kotlin может читать различные типы аннотаций nullability, чтобы получать информацию о nullability из Java. Благодаря этой информации он может сообщать о несоответствиях nullability в Kotlin при вызове кода Java.

В Kotlin 1.5.30 можно указать, должен ли компилятор сообщать о несоответствии nullability на основе информации из определённых типов аннотаций nullability. Для этого используйте параметр компилятора -Xnullability-annotations=@<package-name>:<report-level>. В аргументе укажите полное имя пакета аннотаций nullability и один из следующих уровней отчётности:

  • ignore — игнорировать несоответствия nullability

  • warn — выдавать предупреждения

  • strict — выдавать ошибки.

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

Пример включения сообщений об ошибках для новых аннотаций nullability в RxJava 3: -Xnullability-annotations=@io.reactivex.rxjava3.annotations:strict. Обратите внимание, что по умолчанию все такие несоответствия nullability являются предупреждениями.

Kotlin/Native

В Kotlin/Native появились различные изменения и улучшения:

  • Поддержка Apple silicon

  • Улучшенный Kotlin DSL для плагина CocoaPods Gradle

  • Экспериментальная совместимость со Swift 5.5 async/await

  • Улучшенное сопоставление объектов и объектов-компаньонов со Swift/Objective-C

  • Отказ от связывания с DLL без библиотек импорта для целей MinGW

Поддержка Apple silicon

В Kotlin 1.5.30 добавлена нативная поддержка Apple silicon.

Ранее для работы компилятора и инструментов Kotlin/Native на компьютерах Apple silicon требовалась среда трансляции Rosetta. В Kotlin 1.5.30 среда трансляции больше не нужна — компилятор и инструменты могут работать на оборудовании Apple silicon без дополнительных действий.

Мы также добавили новые цели, которые позволяют запускать код Kotlin нативно на Apple silicon:

  • macosArm64

  • iosSimulatorArm64

  • watchosSimulatorArm64

  • tvosSimulatorArm64

Они доступны как на компьютерах Intel, так и на Apple silicon. Все существующие цели также доступны на компьютерах Apple silicon.

Обратите внимание, что в версии 1.5.30 плагин Gradle kotlin-multiplatform обеспечивает только базовую поддержку целей Apple silicon. В частности, новые цели симулятора не включены в сокращённые обозначения целей ios, tvos и watchos. Мы продолжим работу над улучшением пользовательского опыта с новыми целями.

Улучшенный Kotlin DSL для плагина CocoaPods Gradle

Новые параметры фреймворков Kotlin/Native

В Kotlin 1.5.30 улучшен DSL плагина CocoaPods Gradle для фреймворков Kotlin/Native. Помимо имени фреймворка, в конфигурации Pod можно указать другие параметры:

  • Указать динамический или статический вариант фреймворка

  • Явно включить экспорт зависимостей

  • Включить встраивание Bitcode

Чтобы использовать новый DSL, обновите проект до Kotlin 1.5.30 и укажите параметры в разделе cocoapods файла build.gradle(.kts):

cocoapods {
    frameworkName = "MyFramework" // This property is deprecated 
    // and will be removed in future versions
    // New DSL for framework configuration:
    framework {
        // All Framework properties are supported
        // Framework name configuration. Use this property instead of 
        // deprecated 'frameworkName'
        baseName = "MyFramework"
        // Dynamic framework support
        isStatic = false
        // Dependency export
        export(project(":anotherKMMModule"))
        transitiveExport = false // This is default.
        // Bitcode embedding
        embedBitcode(BITCODE)
    }
}

Поддержка пользовательских имён конфигураций Xcode

Плагин Kotlin CocoaPods Gradle поддерживает пользовательские имена в конфигурации сборки Xcode. Это также пригодится, если вы используете в Xcode специальные имена для конфигурации сборки, например Staging.

Чтобы указать пользовательское имя, используйте параметр xcodeConfigurationToNativeBuildType в разделе cocoapods файла build.gradle(.kts):

cocoapods {
    // Maps custom Xcode configuration to NativeBuildType
    xcodeConfigurationToNativeBuildType["CUSTOM_DEBUG"] = NativeBuildType.DEBUG
    xcodeConfigurationToNativeBuildType["CUSTOM_RELEASE"] = NativeBuildType.RELEASE
}

Этот параметр не появится в файле Podspec. Когда Xcode запускает процесс сборки Gradle, плагин Kotlin CocoaPods Gradle выбирает необходимый тип нативной сборки.

Объявлять конфигурации Debug и Release не нужно: они поддерживаются по умолчанию.

Экспериментальная совместимость со Swift 5.5 async/await

Совместимость параллельного выполнения со Swift async/await является экспериментальной. Она может быть удалена или изменена в любое время. Используйте её только для оценки. Мы будем признательны за ваш отзыв в YouTrack.

В версии 1.4.0 мы добавили поддержку вызова функций-приостановок Kotlin из Objective-C и Swift, а теперь улучшаем её с учётом новой возможности Swift 5.5 — параллельного выполнения с модификаторами async и await.

Теперь компилятор Kotlin/Native добавляет атрибут _Nullable_result в сгенерированные заголовки Objective-C для функций-приостановок с nullable-типами возвращаемого значения. Благодаря этому их можно вызывать из Swift как функции async с корректной nullability.

Обратите внимание, что эта возможность является экспериментальной и в будущем на неё могут повлиять изменения как в Kotlin, так и в Swift. Пока мы предлагаем предварительную версию с определёнными ограничениями и будем рады узнать ваше мнение. Подробнее о текущем состоянии и оставьте отзыв в этой задаче YouTrack.

Улучшенное сопоставление объектов и объектов-компаньонов со Swift/Objective-C

Теперь доступ к объектам и объектам-компаньонам можно получать способом, более интуитивным для разработчиков нативных приложений iOS. Например, если в Kotlin у вас есть следующие объекты:

object MyObject {
    val x = "Some value"
}

class MyClass {
    companion object {
        val x = "Some value"
    }
}

Чтобы получить к ним доступ в Swift, можно использовать свойства shared и companion:

MyObject.shared
MyObject.shared.x
MyClass.companion
MyClass.Companion.shared

Подробнее о совместимости Swift/Objective-C.

Отказ от связывания с DLL без библиотек импорта для целей MinGW

LLD — это компоновщик проекта LLVM, который мы планируем начать использовать в Kotlin/Native для целей MinGW благодаря его преимуществам перед стандартным ld.bfd, прежде всего более высокой производительности.

Однако последняя стабильная версия LLD не поддерживает прямое связывание с DLL для целей MinGW (Windows). Для такого связывания требуются библиотеки импорта. Хотя в Kotlin/Native 1.5.30 они не нужны, мы добавляем предупреждение, чтобы сообщить вам, что такой способ использования несовместим с LLD, который в будущем станет компоновщиком по умолчанию для MinGW.

Поделитесь своими мыслями и опасениями по поводу перехода на компоновщик LLD в этой задаче YouTrack.

Kotlin Multiplatform

В версии 1.5.30 появились следующие важные обновления Kotlin Multiplatform:

  • Возможность использовать пользовательские библиотеки cinterop в общем нативном коде

  • Поддержка XCFrameworks

  • Новая настройка публикации артефактов Android по умолчанию

Возможность использовать пользовательские библиотеки cinterop в общем нативном коде

Kotlin Multiplatform предоставляет возможность использовать платформозависимые библиотеки взаимодействия в общих исходных наборах. До версии 1.5.30 это работало только с библиотеками платформы, поставляемыми вместе с дистрибутивом Kotlin/Native. Начиная с версии 1.5.30 вы можете использовать эту возможность с пользовательскими библиотеками cinterop. Чтобы включить эту функцию, добавьте свойство kotlin.mpp.enableCInteropCommonization=true в файл gradle.properties:

kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.enableCInteropCommonization=true

Поддержка XCFrameworks

Теперь во всех проектах Kotlin Multiplatform XCFrameworks можно использовать в качестве выходного формата. Apple представила XCFrameworks как замену универсальным (fat) фреймворкам. Благодаря XCFrameworks вы можете:

  • Собрать логику для всех целевых платформ и архитектур в один пакет.

  • Не удалять все ненужные архитектуры перед публикацией приложения в App Store.

XCFrameworks полезны, если вы хотите использовать свой фреймворк Kotlin на устройствах и симуляторах Apple M1.

Чтобы использовать XCFrameworks, обновите скрипт build.gradle(.kts):

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

plugins {
    kotlin("multiplatform")
}

kotlin {
    val xcf = XCFramework()
  
    ios {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
    watchos {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
    tvos {
        binaries.framework {
            baseName = "shared"
            xcf.add(this)
        }
    }
}
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFrameworkConfig

plugins {
    id 'org.jetbrains.kotlin.multiplatform'
}

kotlin {
    def xcf = new XCFrameworkConfig(project)

    ios {
        binaries.framework {
            baseName = "shared"
            xcf.add(it)
        }
    }
    watchos {
        binaries.framework {
            baseName = "shared"
            xcf.add(it)
        }
    }
    tvos {
        binaries.framework {
            baseName = "shared"
            xcf.add(it)
        }
    }
}

При объявлении XCFrameworks будут зарегистрированы следующие новые задачи Gradle:

  • assembleXCFramework

  • assembleDebugXCFramework (дополнительный отладочный артефакт, который содержит dSYM)

  • assembleReleaseXCFramework

Подробнее о XCFrameworks можно узнать в этом видео WWDC.

Новая настройка публикации артефактов Android по умолчанию

С помощью плагина Gradle maven-publish вы можете опубликовать свою мультиплатформенную библиотеку для целевой платформы Android, указав имена вариантов Android в скрипте сборки. Плагин Kotlin Gradle автоматически создаст публикации.

До версии 1.5.30 в метаданные метаданные сгенерированной публикации включались атрибуты типа сборки для каждого публикуемого варианта Android, поэтому она была совместима только с тем же типом сборки, который использовал потребитель библиотеки. В Kotlin 1.5.30 появилась новая настройка публикации по умолчанию:

  • Если у всех публикуемых проектом вариантов Android одинаковое значение атрибута типа сборки, опубликованные варианты не будут содержать этот атрибут и будут совместимы с любым типом сборки.

  • Если у опубликованных вариантов разные значения атрибута типа сборки, то без этого атрибута будут опубликованы только варианты со значением release. Благодаря этому варианты release будут совместимы с любым типом сборки на стороне потребителя, а варианты, отличные от release, будут совместимы только с соответствующими типами сборки потребителя.

Чтобы отказаться от этого поведения и сохранить атрибуты типа сборки для всех вариантов, задайте следующее свойство Gradle: kotlin.android.buildTypeAttribute.keep=true.

Kotlin/JS

В версии 1.5.30 в Kotlin/JS появятся два важных улучшения:

  • Бэкенд компилятора JS IR достиг стадии Beta

  • Улучшенная отладка приложений с бэкендом Kotlin/JS IR

Бэкенд компилятора JS IR достиг стадии Beta

Бэкенд компилятора на основе IR для Kotlin/JS, представленный в версии 1.4.0 на стадии Alpha, достиг стадии Beta.

Ранее мы опубликовали руководство по миграции на бэкенд JS IR, чтобы помочь вам перенести проекты на новый бэкенд. Теперь мы хотим представить плагин IDE Kotlin/JS Inspection Pack, который показывает необходимые изменения непосредственно в IntelliJ IDEA.

Улучшенная отладка приложений с бэкендом Kotlin/JS IR

В Kotlin 1.5.30 появилась генерация карт исходного кода JavaScript для бэкенда Kotlin/JS IR. Это улучшит отладку Kotlin/JS при включенном бэкенде IR: будут доступны точки останова, пошаговое выполнение и читаемые трассировки стека с корректными ссылками на исходный код.

Узнайте, как отлаживать Kotlin/JS в браузере или IntelliJ IDEA.

Gradle

В рамках нашей работы над улучшением взаимодействия пользователей с плагином Kotlin Gradle мы реализовали следующие функции:

  • Поддержка цепочек инструментов Java, в том числе возможность указать каталог JDK с помощью интерфейса UsesKotlinJavaToolchain в старых версиях Gradle

  • Более простой способ явно указать аргументы JVM для демона Kotlin

Поддержка цепочек инструментов Java

В Gradle 6.7 появилась функция «Поддержка цепочек инструментов Java». С ее помощью можно:

  • Выполнять компиляцию, тесты и исполняемые файлы с помощью JDK и JRE, отличных от используемых Gradle.

  • Компилировать и тестировать код с еще не выпущенной версией языка.

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

Плагин Kotlin Gradle поддерживает цепочки инструментов Java для задач компиляции Kotlin/JVM. Цепочка инструментов Java:

  • Задает параметр jdkHome, доступный для целей JVM.

    Возможность напрямую задавать параметр jdkHome объявлена устаревшей.

  • Задает значение kotlinOptions.jvmTarget, соответствующее версии JDK из цепочки инструментов, если пользователь явно не задал параметр jvmTarget. Если цепочка инструментов не настроена, для поля jvmTarget используется значение по умолчанию. Подробнее о совместимости целевых платформ JVM.

  • Влияет на то, в какой JDK выполняются рабочие процессы kapt.

Чтобы задать цепочку инструментов, используйте следующий код. Замените заполнитель <MAJOR_JDK_VERSION> версией JDK, которую хотите использовать:

kotlin {
    jvmToolchain {
        (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}
kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}

Обратите внимание: настройка цепочки инструментов через расширение kotlin также обновит цепочку инструментов для задач компиляции Java.

Можно настроить цепочку инструментов через расширение java, и задачи компиляции Kotlin будут ее использовать:

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(<MAJOR_JDK_VERSION>)) // "8"
    }
}

Информацию о настройке любой версии JDK для задач KotlinCompile см. в документации о настройке версии JDK с помощью Task DSL.

Для версий Gradle от 6.1 до 6.6 используйте интерфейс UsesKotlinJavaToolchain, чтобы задать каталог JDK.

Возможность указать каталог JDK с помощью интерфейса UsesKotlinJavaToolchain

Все задачи Kotlin, поддерживающие настройку JDK через kotlinOptions, теперь реализуют интерфейс UsesKotlinJavaToolchain. Чтобы задать каталог JDK, укажите путь к JDK вместо заполнителя <JDK_VERSION>:

project.tasks
    .withType<UsesKotlinJavaToolchain>()
    .configureEach {
        it.kotlinJavaToolchain.jdk.use(
            "/path/to/local/jdk",
            JavaVersion.<LOCAL_JDK_VERSION>
        )
    }
project.tasks
    .withType(UsesKotlinJavaToolchain.class)
    .configureEach {
        it.kotlinJavaToolchain.jdk.use(
            '/path/to/local/jdk',
            JavaVersion.<LOCAL_JDK_VERSION>
        )
    }

Используйте интерфейс UsesKotlinJavaToolchain для версий Gradle от 6.1 до 6.6. Начиная с Gradle 6.7 вместо него используйте цепочки инструментов Java.

При использовании этой функции учтите, что рабочие процессы задач kapt будут использовать только режим изоляции процессов, а свойство kapt.workers.isolation будет игнорироваться.

Более простой способ явно указать аргументы JVM для демона Kotlin

В Kotlin 1.5.30 появилась новая логика обработки аргументов JVM демона Kotlin. Каждый параметр в следующем списке переопределяет параметры, указанные перед ним:

  • Если ничего не указано, демон Kotlin наследует аргументы демона Gradle (как и раньше). Например, в файле gradle.properties:

    org.gradle.jvmargs=-Xmx1500m -Xms=500m
    
  • Если аргументы JVM демона Gradle содержат системное свойство kotlin.daemon.jvm.options, оно используется, как и раньше:

    org.gradle.jvmargs=-Dkotlin.daemon.jvm.options=-Xmx1500m -Xms=500m
    
  • Можно добавить свойство kotlin.daemon.jvmargs в файл gradle.properties:

    kotlin.daemon.jvmargs=-Xmx1500m -Xms=500m
    
  • Можно указать аргументы в расширении kotlin:

    kotlin {
        kotlinDaemonJvmArgs = listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC")
    }
    
    kotlin {
        kotlinDaemonJvmArgs = ["-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"]
    }
    
  • Можно указать аргументы для конкретной задачи:

    tasks
        .matching { it.name == "compileKotlin" && it is CompileUsingKotlinDaemon }
        .configureEach {
            (this as CompileUsingKotlinDaemon).kotlinDaemonJvmArguments.set(listOf("-Xmx486m", "-Xms256m", "-XX:+UseParallelGC"))
        }
    
    tasks
        .matching {
            it.name == "compileKotlin" && it instanceof CompileUsingKotlinDaemon
        }
        .configureEach {
            kotlinDaemonJvmArguments.set(["-Xmx1g", "-Xms512m"])
        }
    

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

Дополнительную информацию о демоне Kotlin см. в разделе Демон Kotlin и его использование с Gradle.

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

В Kotlin 1.5.30 улучшены API Duration и Regex стандартной библиотеки:

  • Изменение результата Duration.toString()

  • Разбор Duration из строки

  • Поиск совпадения с Regex в заданной позиции

  • Разбиение Regex в последовательность

Изменение результата Duration.toString()

API Duration имеет статус Experimental. В любой момент его могут удалить или изменить. Используйте его только для ознакомления. Мы будем рады получить ваши отзывы в YouTrack.

До Kotlin 1.5.30 функция Duration.toString() возвращала строковое представление аргумента в единице измерения, позволяющей получить наиболее компактное и понятное числовое значение. Теперь она возвращает строковое значение в виде комбинации числовых компонентов, каждый из которых выражен в своей единице измерения. Каждый компонент — это число, за которым следует сокращенное название единицы измерения: d, h, m, s. Например:

Пример вызова функции

Предыдущий результат

Текущий результат

Duration.days(45).toString()

45.0d

45d

Duration.days(1.5).toString()

36.0h

1d 12h

Duration.minutes(1230).toString()

20.5h

20h 30m

Duration.minutes(2415).toString()

40.3h

1d 16h 15m

Duration.minutes(920).toString()

920m

15h 20m

Duration.seconds(1.546).toString()

1.55s

1.546s

Duration.milliseconds(25.12).toString()

25.1ms

25.12ms

Изменился и способ представления отрицательных длительностей. Отрицательная длительность начинается со знака минус (-), а если она состоит из нескольких компонентов, то заключается в скобки: -12m и -(1h 30m).

Обратите внимание, что небольшие длительности менее одной секунды представляются одним числом с одной из единиц измерения меньше секунды. Например, ms (миллисекунды), us (микросекунды) или ns (наносекунды): 140.884ms, 500us, 24ns. Научная нотация для их представления больше не используется.

Чтобы представить длительность в одной единице измерения, используйте перегруженную функцию Duration.toString(unit, decimals).

В некоторых случаях, включая сериализацию и обмен данными, мы рекомендуем использовать Duration.toIsoString(). Duration.toIsoString() использует более строгий формат ISO-8601 вместо Duration.toString().

Разбор Duration из строки

API Duration имеет статус Experimental. В любой момент его могут удалить или изменить. Используйте его только для ознакомления. Мы будем рады получить ваши отзывы в этом обсуждении.

В Kotlin 1.5.30 в API Duration появились новые функции:

  • parse(), которая поддерживает разбор результатов:

    • toString().

    • toString(unit, decimals).

    • toIsoString().

  • parseIsoString(), которая разбирает только строки в формате, создаваемом функцией toIsoString().

  • parseOrNull() и parseIsoStringOrNull(), которые работают как описанные выше функции, но возвращают null вместо того, чтобы выбрасывать IllegalArgumentException при недопустимом формате длительности.

Примеры использования parse() и parseOrNull():

import kotlin.time.Duration
import kotlin.time.ExperimentalTime

@ExperimentalTime
fun main() {
//sampleStart
    val isoFormatString = "PT1H30M"
    val defaultFormatString = "1h 30m"
    val singleUnitFormatString = "1.5h"
    val invalidFormatString = "1 hour 30 minutes"
    println(Duration.parse(isoFormatString)) // "1h 30m"
    println(Duration.parse(defaultFormatString)) // "1h 30m"
    println(Duration.parse(singleUnitFormatString)) // "1h 30m"
    //println(Duration.parse(invalidFormatString)) // throws exception
    println(Duration.parseOrNull(invalidFormatString)) // "null"
//sampleEnd
}

А вот примеры использования parseIsoString() и parseIsoStringOrNull():

import kotlin.time.Duration
import kotlin.time.ExperimentalTime

@ExperimentalTime
fun main() {
//sampleStart
    val isoFormatString = "PT1H30M"
    val defaultFormatString = "1h 30m"
    println(Duration.parseIsoString(isoFormatString)) // "1h 30m"
    //println(Duration.parseIsoString(defaultFormatString)) // throws exception
    println(Duration.parseIsoStringOrNull(defaultFormatString)) // "null"
//sampleEnd
}

Поиск совпадения с Regex в заданной позиции

Функции Regex.matchAt() и Regex.matchesAt() имеют статус Experimental. В любой момент их могут удалить или изменить. Используйте их только для ознакомления. Мы будем рады получить ваши отзывы в YouTrack.

Новые функции Regex.matchAt() и Regex.matchesAt() позволяют проверить, есть ли точное совпадение с регулярным выражением в заданной позиции в String или CharSequence.

Функция matchesAt() возвращает логическое значение:

fun main(){
//sampleStart
    val releaseText = "Kotlin 1.5.30 is released!"
    // regular expression: one digit, dot, one digit, dot, one or more digits
    val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
    println(versionRegex.matchesAt(releaseText, 0)) // "false"
    println(versionRegex.matchesAt(releaseText, 7)) // "true"
//sampleEnd
}

Функция matchAt() возвращает совпадение, если оно найдено, или null, если совпадения нет:

fun main(){
//sampleStart
    val releaseText = "Kotlin 1.5.30 is released!"
    val versionRegex = "\\d[.]\\d[.]\\d+".toRegex()
    println(versionRegex.matchAt(releaseText, 0)) // "null"
    println(versionRegex.matchAt(releaseText, 7)?.value) // "1.5.30"
//sampleEnd
}

Разбиение Regex в последовательность

Функции Regex.splitToSequence() и CharSequence.splitToSequence(Regex) имеют статус Experimental. В любой момент их могут удалить или изменить. Используйте их только для ознакомления. Мы будем рады получить ваши отзывы в YouTrack.

Новая функция Regex.splitToSequence() — это ленивый аналог функции split(). Она разбивает строку по совпадениям с заданным регулярным выражением, но возвращает результат в виде Sequence, поэтому все операции с результатом выполняются лениво.

fun main(){
//sampleStart
    val colorsText = "green, red , brown&blue, orange, pink&green"
    val regex = "[,\\s]+".toRegex()
    val mixedColor = regex.splitToSequence(colorsText)
        .onEach { println(it) }
        .firstOrNull { it.contains('&') }
    println(mixedColor) // "brown&blue"
//sampleEnd
}

Похожая функция также добавлена в CharSequence:

    val mixedColor = colorsText.splitToSequence(regex)

Serialization 1.3.0-RC

Выпущена kotlinx.serialization версия 1.3.0-RC с новыми возможностями сериализации JSON:

  • Сериализация потоков Java IO

  • Управление значениями по умолчанию на уровне свойств

  • Возможность исключать значения null из сериализации

  • Пользовательские дискриминаторы классов при полиморфной сериализации

Подробнее см. в списке изменений.

11 мая 2026
Руководство по совместимости Kotlin 1.6.xЧто нового в Kotlin 1.5.20

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

Spec-Zone.ru

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