Spec-Zone.ru › Kotlin 2

Что нового в Kotlin 2.4.20-RC3

Выпущена: 2 сентября 2026 г.

В этом документе описаны не все возможности выпуска Early Access Preview (EAP), а лишь некоторые важные улучшения.

Полный список изменений см. в журнале изменений на GitHub.

Вышел Kotlin 2.4.20-RC3! Вот некоторые подробности об этом выпуске EAP:

  • Стандартная библиотека: поддержка восстановления трассировки стека корутин и новые функции для проверки равенства и уникальности элементов коллекции

  • Kotlin/Native: новые возможности экспорта в Swift и автоматическая генерация файлов Package.swift для зависимостей SwiftPM

  • Kotlin/Wasm: изменения в вызовах require() верхнего уровня в объявлениях @JsFun, улучшенный порядок инициализации объектов-компаньонов и поддержка Wasmtime в плагине Kotlin Gradle

  • Kotlin/JS: новый DSL для тестирования в браузере и поддержка экспорта suspend-лямбд в виде асинхронных функций

  • API средств сборки: поддержка новых целевых платформ: Kotlin/JS, Kotlin/Wasm и метаданных Kotlin

  • Компилятор Kotlin: экспериментальный выпуск нативного образа

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

Обновление до Kotlin 2.4.20-RC3

Последняя версия Kotlin включена в последние версии IntelliJ IDEA и Android Studio.

Чтобы обновиться до новой версии Kotlin, убедитесь, что ваша IDE обновлена до последней версии, и измените версию Kotlin на 2.4.20-RC3 в скриптах сборки.

Новые возможности

В этом выпуске доступны следующие предварительные возможности. Сюда входят возможности со статусами Beta, Alpha и Experimental:

  • Стандартная библиотека: поддержка восстановления трассировки стека корутин

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

  • Kotlin/JS: новый DSL для тестирования в браузере

  • API средств сборки: поддержка Kotlin/JS, Kotlin/Wasm и метаданных Kotlin

  • Компилятор Kotlin: отдельный образ компилятора Kotlin

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

В Kotlin 2.4.20-RC3 добавлена поддержка восстановления трассировки стека корутин, а также новые функции для проверки равенства и уникальности элементов коллекции.

Поддержка восстановления трассировки стека корутин

В Kotlin 2.4.20-RC3 в стандартную библиотеку добавлен интерфейс StackTraceRecoverable. Это улучшает интеграцию с библиотекой kotlinx.coroutines, поскольку позволяет определить, как создавать новые экземпляры исключений для восстановления трассировки стека, не добавляя зависимость от kotlinx.coroutines.

Восстановление трассировки стека помогает при отладке, когда одна корутина выбрасывает исключение, а другая повторно его выбрасывает. Оно позволяет увидеть, где возникло исключение и где другая корутина повторно его выбросила.

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

Если конструктору исключения требуются дополнительные аргументы, например номер строки или код ошибки, реализуйте интерфейс StackTraceRecoverable, чтобы определить, как библиотека kotlinx.coroutines создает новый экземпляр этого исключения.

Чтобы реализовать интерфейс, переопределите функцию copyForStackTraceRecovery(). В переопределении верните новый экземпляр исключения для восстановления трассировки стека или null, если не хотите, чтобы библиотека kotlinx.coroutines копировала исключение.

Интерфейс StackTraceRecoverable доступен на всех целевых платформах, но библиотека kotlinx.coroutines использует его для восстановления трассировки стека только на JVM.

Эти API имеют статус Experimental и требуют явного согласия с помощью аннотации @OptIn(ExperimentalStdlibCoroutineSupportApi::class).

Ниже приведен пример пользовательского исключения, которое сохраняет свойство line при создании нового экземпляра для восстановления трассировки стека:

import kotlin.coroutines.ExperimentalStdlibCoroutineSupportApi
import kotlin.coroutines.debug.StackTraceRecoverable

@OptIn(ExperimentalStdlibCoroutineSupportApi::class)
class FileEditException
// The implementation requires a private constructor
// to pass the cause to the IllegalStateException constructor
private constructor(
    val line: Int,
    private val detail: String,
    cause: Throwable?,
) : IllegalStateException("When editing line $line: $detail", cause),
    // Implements StackTraceRecoverable for stack trace recovery
    StackTraceRecoverable<FileEditException> {

    constructor(line: Int, detail: String) : this(line, detail, null)

    // Copies the line number and message details
    override fun copyForStackTraceRecovery(): FileEditException =
        FileEditException(line, detail, this)
    }

fun main() {
    val original = FileEditException(15, "Unexpected token")
    
    // Normally, you don't need to call this function directly unless you're testing its behavior
    // The kotlinx.coroutines library invokes it automatically during stack trace recovery
    val copy = original.copyForStackTraceRecovery()

    println(copy.message)
    // When editing line 15: Unexpected token

    println(copy.cause == original)
    // true
}

Дополнительную информацию см. в KEEP этой возможности.

Будем благодарны за ваши отзывы в YouTrack.

Новые функции для проверки равенства и уникальности элементов коллекции

До выхода Kotlin 2.4.20-RC3 для проверки того, что все элементы коллекции различны или равны, приходилось использовать неэффективные шаблоны кода.

В Kotlin 2.4.20-RC3 добавлены экспериментальные функции, решающие эту задачу:

Функция

Проверяет

.allDistinct()

Уникальность каждого значения в коллекции.

.allDistinctBy()

Уникальность значения выбранного свойства у каждого объекта.

.allEqual()

Равенство всех значений в коллекции.

.allEqualBy()

Равенство значений выбранного свойства у всех объектов.

Эти функции можно использовать с коллекциями, последовательностями и массивами. Они сравнивают элементы с помощью структурного равенства, как и другие операции с коллекциями.

Эти функции имеют статус Experimental и требуют явного согласия с помощью аннотации @OptIn(ExperimentalStdlibApi::class) или параметра компилятора -opt-in=kotlin.ExperimentalStdlibApi:

@OptIn(ExperimentalStdlibApi::class)
fun main() {
    data class Response(
        val participantId: String,
        val answer: String,
        val responseDate: String
    )

    val responses = listOf(
        Response("P001", "Yes", "2026-07-21"),
        Response("P002", "Maybe", "2026-07-21"),
        Response("P003", "No", "2026-07-21")
    )

    // Checks if all participants gave the same answer
    println(responses.allEqualBy { it.answer })
    // false

    // Checks for duplicate participants
    println(responses.allDistinctBy { it.participantId })
    // true

    // Checks if all responses were submitted on the same date
    println(responses.allEqualBy { it.responseDate })
    // true

    val answers = responses.map { it.answer }

    // Checks if answers are identical
    println(answers.allEqual())
    // false

    // Checks if answers are distinct
    println(answers.allDistinct())
    // true
}

Будем рады узнать о вашем опыте использования этих функций и получить отзывы в YouTrack.

Kotlin/Native

В Kotlin 2.4.20-RC3 добавлены новые возможности экспорта в Swift, включая поддержку sealed-классов и межъязыкового наследования, а также автоматическая генерация файлов Package.swift для зависимостей SwiftPM.

Новые возможности экспорта в Swift

Sealed-классы

В Kotlin 2.4.20-RC3 добавлена поддержка sealed-классов и интерфейсов при экспорте в Swift.

Раньше для каждого оператора switch над sealed-типом приходилось записывать вариант default. Теперь sealed-иерархии, объявленные в Kotlin, преобразуются в перечисления Swift, что позволяет использовать исчерпывающие операторы switch с полной поддержкой автодополнения в Xcode.

При экспорте в Swift для каждого sealed-типа создается метод .sealedType(). Этот метод возвращает перечисление Swift, варианты которого соответствуют непосредственным подклассам sealed-иерархии. Эти вызовы можно вкладывать, чтобы сопоставлять более глубокие уровни иерархии.

Например, объявите в Kotlin sealed-интерфейс с иерархией классов:

// Kotlin
sealed interface Shape

class Circle : Shape {
   override fun toString(): String = "Circle"
}

class Rectangle : Shape {
   override fun toString(): String = "Rectangle"
}

fun createCircle(): Shape = Circle()

На стороне Swift можно использовать исчерпывающий switch без варианта default:

// Swift
let shape = createCircle()

let name = switch shape.sealedType() {
   case let .circle(type): "It's a \(type.value)"
   case let .rectangle(type): "It's a \(type.value)"
}
// name == "It's a Circle"

Поскольку switch является исчерпывающим, компилятор предупредит вас, если в sealed-иерархию будет добавлен новый подкласс. Так вы сможете сразу обработать его, не полагаясь на вариант default.

Межъязыковое наследование при экспорте в Swift

В Kotlin 2.4.20-RC3 добавлена поддержка межъязыкового наследования при экспорте в Swift.

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

Чтобы реализовать этот шаблон, объявите в Kotlin суперкласс, от которого будет наследоваться реализация на Swift, а также интерфейс Kotlin. Затем реализуйте интерфейс в Swift и передайте объект Swift функциям Kotlin, принимающим этот интерфейс. Например, для библиотеки CryptoKit:

  1. На стороне Kotlin объявите базовый класс open и интерфейс Kotlin с функцией, которая принимает его:

    // Kotlin
    interface CryptoProvider {
       fun hashMD5(input: String): String
    }
    
    fun processHash(provider: CryptoProvider, input: String): String = provider.hashMD5(input)
    
    open class SwiftBase 
    
  2. На стороне Swift унаследуйте класс SwiftBase, экспортированный из Kotlin, реализуйте интерфейс с помощью библиотеки на чистом Swift и передайте объект обратно в Kotlin:

    // Swift
    import CryptoKit
    
    final class IosCryptoProvider: SwiftBase, CryptoProvider {
       func hashMD5(input: String) -> String {
           guard let data = input.data(using: .utf8) else { return "failed" }
           return Insecure.MD5.hash(data: data).description
       }
    }
    
    let provider = IosCryptoProvider()
    
    // The call is dispatched to the Swift implementation
    print(processHash(provider: provider, input: "Hello, world!"))
    

Получив объект Swift, Kotlin воспринимает его как реализацию обычного интерфейса и выполняет код Swift.

Дополнительную информацию об экспорте в Swift см. в нашей документации.

Генерация Package.swift для зависимостей SwiftPM

При экспорте XCFramework с зависимостями от пакетов SwiftPM необходимо опубликовать полученный пакет SwiftPM, чтобы он разрешался правильно. Для этого задача Gradle assembleSharedXCFramework теперь создает файл Package.swift, который следует распространять вместе с XCFramework.

Подробности см. на странице экспорта SwiftPM.

Kotlin/Wasm

В Kotlin 2.4.20-RC3 изменен способ обработки Kotlin/Wasm вызовов require() верхнего уровня в объявлениях @JsFun, порядок инициализации объектов-компаньонов приведен в соответствие с поведением JVM, а в плагин Kotlin Gradle добавлена поддержка Wasmtime в качестве среды выполнения для целевой платформы wasmWasi.

Изменения в вызовах require() верхнего уровня в объявлениях @JsFun

Теперь Kotlin/Wasm сообщает об ошибке, если объявление @JsFun использует функцию require() верхнего уровня.

Раньше компилятор создавал переменную require в файле import-object.mjs, позволяя объявлениям @JsFun вызывать require().

Такое поведение непреднамеренно раскрывала деталь реализации компилятора. Чтобы упростить переход с него, Kotlin/Wasm удаляет это сгенерированное объявление require, и теперь компилятор сообщает об ошибках при таких вызовах. Например:

// Reports an error
@JsFun("(mod) => require(mod)")
external fun loadModule(mod: String): JsAny

Чтобы подготовиться к этому изменению, замените вызовы require() верхнего уровня в объявлениях @JsFun аннотацией @JsModule:

@JsModule("module")
external val module: Module

external interface Module {
    // Defines the expected module members
}

Для динамической загрузки модулей используйте выражение import(). Добавьте магический комментарий /* webpackIgnore: true */, чтобы предотвратить анализ динамического импорта инструментом webpack:

@JsFun("""
    ((module) => () => module)(
        await import(/* webpackIgnore: true */ "module")
    )
""")
private external fun loadModuleDynamically(): JsAny?

Выражение import() также можно использовать условно. Например, можно загружать модуль только при запуске в Node.js:

@JsFun("""
    ((module) => () => module)(
        ((typeof process !== "undefined") && (process.release.name === "node"))
            ? await import(/* webpackIgnore: true */ "module")
            : null
    )
""")
private external fun loadNodeModule(): JsAny?

Если ваш проект зависит от библиотек, которым требуется функция require() верхнего уровня, в качестве обходного решения добавьте ее как свойство globalThis:

@JsFun("""
    ((module) => {
        globalThis.require = module.default.createRequire(import.meta.url)
        return () => {}
    })(await import("node:module"))
""")
external fun defineRequire()

Если у вас возникнут проблемы, поделитесь отзывом в нашем трекере задач.

Улучшенный порядок инициализации объектов-компаньонов

Теперь Kotlin/Wasm инициализирует объекты-компаньоны суперклассов перед объектами-компаньонами подклассов, как и JVM. Раньше порядок инициализации мог быть обратным, что приводило к несогласованному поведению на разных платформах.

Это обновление повышает согласованность между платформами и уменьшает платформенные различия в поведении при инициализации классов. Кроме того, оно обеспечивает правильную обработку инициализации объектов-компаньонов в глубоких иерархиях наследования, в том числе в случаях, когда промежуточные классы не объявляют объекты-компаньоны.

Поддержка Wasmtime в плагине Kotlin Gradle

В Kotlin 2.4.20-RC3 добавлена поддержка Wasmtime в качестве среды выполнения для целевой платформы wasmWasi в плагине Kotlin Gradle.

Раньше для целевой платформы wasmWasi поддерживалась только среда выполнения Node.js, для которой требовалась загрузка JavaScript-кода для запуска приложений WASI. Благодаря поддержке Wasmtime теперь можно запускать приложения Kotlin/Wasm в автономной среде выполнения WebAssembly.

Чтобы использовать Wasmtime в качестве среды выполнения для целевой платформы wasmWasi, добавьте wasmtime() в файл сборки Gradle:

kotlin {
    wasmWasi {
        wasmtime()
    }
}

Будем благодарны за ваши отзывы в YouTrack.

Kotlin/JS

В Kotlin 2.4.20-RC3 добавлен новый экспериментальный DSL для тестирования в браузере и поддержка экспорта suspend-лямбд в виде асинхронных функций JavaScript.

Новый DSL для тестирования в браузере

В Kotlin 2.4.20-RC3 добавлен новый экспериментальный DSL для запуска тестов Kotlin/JS в браузере.

Сейчас плагин Kotlin Gradle использует Karma в качестве средства запуска браузеров для выполнения тестов JavaScript в разных браузерах. Проект Karma уже два года считается устаревшим, поэтому мы начали изучать альтернативные способы поддержки тестирования в браузере.

Новый DSL призван заменить Karma в качестве инструмента, управляющего различными средствами, и включает:

  • Mocha в качестве средства запуска тестов.

  • Webpack в качестве сборщика (в будущих выпусках он будет заменен на Vite).

  • Playwright в качестве драйвера браузера и средства управления дистрибутивами, поддерживающего браузерные движки Chromium, Firefox и WebKit (Safari).

Чтобы попробовать новый DSL для тестирования, добавьте блок явного согласия test{} внутрь browser{} для целевой платформы Kotlin/JS:

import org.jetbrains.kotlin.gradle.ExperimentalJsTestDsl
import kotlin.time.Duration.Companion.seconds

kotlin {
    js {
        browser {
            @OptIn(ExperimentalJsTestDsl::class)
            // Add and configure the new test{} block
            test {
                // Configure default timeout for all runners
                timeout = 2.seconds
                // Configure headless mode using Gradle providers
                headless = providers
                    .environmentVariable("IS_IN_CI")
                    .map { it.toBoolean() }
                    .orElse(false)
                // Enable and configure Chromium test runner
                chromium {
                    // Override the common timeout option
                    timeout = 5.seconds
                    // Add extra launch arguments
                    launchArgs.add("--no-sandbox")
                }
                // Enable Firefox test runner
                firefox()
                // Enable WebKit test runner
                webkit()
                // Enable and configure an additional WebKit test runner
                webkit("noheadless") {
                    // Set up custom options
                    headless = false
                }
            }
        }
    }
}

Новый DSL активно разрабатывается. Будем благодарны за ваши отзывы в YouTrack.

Поддержка экспорта suspend-лямбд в виде асинхронных функций

В Kotlin 2.4.20-RC3 можно экспортировать лямбда-выражения с модификатором suspend в виде функций JavaScript async.

Раньше из библиотек Kotlin/JS нельзя было экспортировать объявления, содержащие suspend-лямбды. Теперь компилятор Kotlin автоматически выполняет сопряжение между функциями Kotlin suspend и встроенной моделью JavaScript async/await, что полезно для проектов со смешанным кодом Kotlin и TypeScript.

Чтобы включить эту возможность, добавьте следующий параметр компилятора в файл build.gradle.kts:

kotlin {
    js {
        compilations.all {
            compileTaskProvider.configure {
                compilerOptions {
                    freeCompilerArgs.add("-Xsuspend-lambda-exporting")
                }
            }
        }
    }
}

Затем пометьте соответствующие объявления аннотацией @JsExport:

// Kotlin
@JsExport
class TaskRunner {
    suspend fun runTask(task: suspend () -> String): String {
        return task()
    }
}

Со стороны TypeScript suspend-лямбда выглядит как обычная функция async:

// TypeScript
import { TaskRunner } from "..."

const runner = new TaskRunner();
const result = await runner.runTask(async () => "done");
console.log(result); // "done"

Дополнительную информацию об аннотации @JsExport см. в нашей документации.

API средств сборки

Поддержка Kotlin/JS, Kotlin/Wasm и метаданных Kotlin

В Kotlin 2.2.0 API средств сборки (BTA) стал доступен для Kotlin/JVM. В Kotlin 2.4.20-RC3 сделан следующий шаг к стабилизации BTA — добавлена поддержка новых целевых платформ: Kotlin/JS, Kotlin/Wasm и метаданных Kotlin.

Это позволяет плагину Kotlin Gradle более последовательно взаимодействовать с компилятором. В некоторых случаях также можно добиться более быстрой и стабильной компиляции.

BTA — это универсальный API, выступающий в качестве уровня абстракции между системами сборки и экосистемой компилятора Kotlin. Он упрощает поддержку возможностей Kotlin и совместимость с компилятором Kotlin в доступных средствах сборки.

В Kotlin 2.4.20-RC3 BTA доступен для новых целевых платформ в виде возможности, требующей явного включения. Чтобы попробовать его, добавьте соответствующие свойства в файл gradle.properties:

kotlin.wasm.runViaBuildToolsApi=true
kotlin.js.runViaBuildToolsApi=true
kotlin.metadata.runViaBuildToolsApi=true

Начиная с Kotlin 2.5.0 мы планируем включить BTA по умолчанию для Kotlin/JS, Kotlin/Wasm и метаданных Kotlin.

Если вас интересует предложение BTA или вы хотите поделиться отзывом, ознакомьтесь с этим KEEP.

Компилятор Kotlin: нативный образ

В Kotlin 2.4.20-RC3 представлен первый выпуск нативного образа компилятора Kotlin со статусом Experimental. Нативный образ служит полноценной заменой стандартному инструменту командной строки kotlinc, обеспечивая при этом более быстрый запуск и высокую производительность.

Чтобы попробовать нативный образ, скачайте сборку на странице выпусков GitHub.

В нативный образ также включены следующие плагины компилятора, которые можно использовать с параметрами CLI -Xplugin или -Xcompiler-plugin:

  • Serialization

  • Компилятор Compose

  • All-open

  • no-arg

  • SAM with receiver

  • Assignment

  • Lombok

  • Power-assert

Дополнительную информацию о нативном образе компилятора Kotlin см. в файле README.

26 августа 2026 г.
Что нового в Kotlin 2.4.20Что нового в Kotlin 2.4.0

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

Spec-Zone.ru

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