Spec-Zone.ru › Kotlin 2

Что нового в Kotlin 1.5.0

Выпущен: 5 мая 2021 г.

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

Обзор изменений также представлен в публикации о выпуске в блоге.

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

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

В Kotlin 1.5.0 появились стабильные версии новых языковых возможностей, представленных в качестве предварительной версии в 1.4.30:

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

  • Запечатанные интерфейсы и улучшения запечатанных классов

  • Инлайн-классы

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

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

Java быстро развивается, и чтобы обеспечить совместимость Kotlin с ней, мы добавили поддержку одной из последних возможностей языка — классов-записей.

Поддержка записей JVM в Kotlin обеспечивает двустороннюю совместимость:

  • В коде Kotlin классы-записи Java можно использовать так же, как обычные классы со свойствами.

  • Чтобы использовать класс Kotlin в качестве записи в коде Java, объявите его классом data и пометьте аннотацией @JvmRecord.

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

Подробнее об использовании записей JVM в Kotlin.

Запечатанные интерфейсы

Теперь интерфейсам Kotlin можно задавать модификатор sealed, который работает так же, как и для классов: все реализации запечатанного интерфейса известны во время компиляции.

sealed interface Polygon

Например, это позволяет писать исчерпывающие выражения when.

fun draw(polygon: Polygon) = when (polygon) {
   is Rectangle -> // ...
   is Triangle -> // ...
   // else is not needed - all possible implementations are covered
}

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

class FilledRectangle: Polygon, Fillable

Подробнее о запечатанных интерфейсах.

Иерархии запечатанных классов в пределах пакета

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

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

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

Подробнее об иерархиях запечатанных классов.

Инлайн-классы

Инлайн-классы — это подмножество классов, основанных на значениях, которые хранят только значения. Их можно использовать как обёртки для значения определённого типа без дополнительных накладных расходов, связанных с выделением памяти.

Инлайн-классы можно объявлять, указывая модификатор value перед именем класса:

value class Password(val s: String)

Для бэкенда JVM также требуется специальная аннотация @JvmInline:

@JvmInline
value class Password(val s: String)

Модификатор inline теперь объявлен устаревшим с предупреждением.

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

Kotlin/JVM

В Kotlin/JVM появилось несколько внутренних и пользовательских улучшений. Вот наиболее важные из них:

  • Стабильный IR-бэкенд JVM

  • Новая целевая версия JVM по умолчанию: 1.8

  • SAM-адаптеры через invokedynamic

  • Лямбда-выражения через invokedynamic

  • Устаревание @JvmDefault и старых режимов Xjvm-default

  • Улучшения обработки аннотаций nullability

Стабильный IR-бэкенд JVM

Бэкенд на основе IR для компилятора Kotlin/JVM теперь имеет стабильный статус и включён по умолчанию.

Начиная с Kotlin 1.4.0, ранние версии бэкенда на основе IR были доступны в предварительной версии. Теперь он стал бэкендом по умолчанию для языковой версии 1.5. Для более ранних версий языка по умолчанию по-прежнему используется старый бэкенд.

Подробнее о преимуществах IR-бэкенда и его дальнейшем развитии можно узнать в этой публикации в блоге.

Если в Kotlin 1.5.0 необходимо использовать старый бэкенд, добавьте следующие строки в файл конфигурации проекта:

  • Для 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 по умолчанию: 1.8

Теперь целевая версия по умолчанию для компиляции Kotlin/JVM — 1.8. Целевая версия 1.6 объявлена устаревшей.

Если вам нужна сборка для JVM 1.6, эту целевую версию по-прежнему можно выбрать. Узнайте, как это сделать:

  • в Gradle

  • в Maven

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

SAM-адаптеры через invokedynamic

В Kotlin 1.5.0 для компиляции преобразований SAM (Single Abstract Method) теперь используются динамические вызовы (invokedynamic):

  • Для любого выражения, если тип SAM — это интерфейс Java

  • Для лямбда-выражения, если тип SAM — это функциональный интерфейс Kotlin

В новой реализации используется LambdaMetafactory.metafactory(), а вспомогательные классы-обёртки больше не генерируются при компиляции. Это уменьшает размер JAR-файла приложения и повышает скорость запуска JVM.

Чтобы вернуться к старой реализации, основанной на генерации анонимных классов, добавьте параметр компилятора -Xsam-conversions=class.

Узнайте, как добавлять параметры компилятора в Gradle, Maven и компиляторе командной строки.

Лямбда-выражения через invokedynamic

Компиляция обычных лямбда-выражений Kotlin в invokedynamic имеет экспериментальный статус. Возможность может быть удалена или изменена в любой момент. Для её использования требуется явное согласие (подробности ниже); применять её следует только для оценки. Будем признательны за ваши отзывы на YouTrack.

В Kotlin 1.5.0 появилась экспериментальная поддержка компиляции обычных лямбда-выражений Kotlin (которые не преобразуются в экземпляр функционального интерфейса) в динамические вызовы (invokedynamic). Благодаря использованию LambdaMetafactory.metafactory() эта реализация создаёт более компактные бинарные файлы, эффективно генерируя необходимые классы во время выполнения. По сравнению с обычной компиляцией лямбда-выражений у неё есть три ограничения:

  • Лямбда-выражение, скомпилированное в invokedynamic, не сериализуемо.

  • Вызов toString() для такой лямбда-функции возвращает менее удобное для чтения строковое представление.

  • Экспериментальный API reflect не поддерживает лямбда-выражения, созданные с помощью LambdaMetafactory.

Чтобы опробовать эту возможность, добавьте параметр компилятора -Xlambdas=indy. Будем признательны, если вы поделитесь отзывами в этом запросе YouTrack.

Узнайте, как добавлять параметры компилятора в Gradle, Maven и компиляторе командной строки.

Устаревание @JvmDefault и старых режимов Xjvm-default

До Kotlin 1.4.0 существовала аннотация @JvmDefault, а также режимы -Xjvm-default=enable и -Xjvm-default=compatibility. Они позволяли создавать метод JVM по умолчанию для любого конкретного неабстрактного члена интерфейса Kotlin.

В Kotlin 1.4.0 мы представили новые режимы Xjvm-default, которые включают генерацию методов по умолчанию для всего проекта.

В Kotlin 1.5.0 мы объявляем устаревшими @JvmDefault и старые режимы Xjvm-default: -Xjvm-default=enable и -Xjvm-default=compatibility.

Подробнее о методах по умолчанию при взаимодействии с Java.

Улучшения обработки аннотаций nullability

Kotlin поддерживает обработку информации о nullability типов Java с помощью аннотаций nullability. В Kotlin 1.5.0 появилось несколько улучшений этой возможности:

  • Теперь обрабатываются аннотации nullability аргументов типов в скомпилированных библиотеках Java, используемых как зависимости.

  • Поддерживаются аннотации nullability с целью TYPE_USE для:

    • Массивов

    • Варга́ргументов

    • Полей

    • Параметров типов и их ограничений

    • Аргументов типов базовых классов и интерфейсов

  • Если у аннотации nullability есть несколько целей, применимых к типу, и одна из них — TYPE_USE, то предпочтение отдаётся TYPE_USE. Например, сигнатура метода @Nullable String[] f() преобразуется в fun f(): Array<String?>!, если @Nullable поддерживает цели TYPE_USE и METHOD.

В этих новых поддерживаемых случаях неправильное указание nullability типа при вызове Java из Kotlin приводит к предупреждениям. Используйте параметр компилятора -Xtype-enhancement-improvements-strict-mode, чтобы включить строгий режим для этих случаев (с сообщениями об ошибках).

Подробнее о безопасности относительно null и платформенных типах.

Kotlin/Native

Производительность и стабильность Kotlin/Native улучшились. Основные изменения:

  • Улучшения производительности

  • Отключение средства проверки утечек памяти

Улучшения производительности

В версии 1.5.0 в Kotlin/Native появились улучшения производительности, ускоряющие как компиляцию, так и выполнение.

Кэши компилятора теперь поддерживаются в режиме отладки для целей linuxX64 (только на хостах Linux) и iosArm64. При включённых кэшах компилятора большинство компиляций в режиме отладки завершаются значительно быстрее, за исключением первой. Измерения показали примерно 200-процентное увеличение скорости на наших тестовых проектах.

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

  • Для linuxX64: kotlin.native.cacheKind.linuxX64=static

  • Для iosArm64: kotlin.native.cacheKind.iosArm64=static

Если после включения кэшей компилятора возникнут проблемы, сообщите о них в наш баг-трекер YouTrack.

Другие улучшения ускоряют выполнение кода Kotlin/Native:

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

  • Вычисление trimIndent() для строковых литералов выполняется во время компиляции.

Отключение средства проверки утечек памяти

Встроенное средство проверки утечек памяти Kotlin/Native по умолчанию отключено.

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

Средство проверки утечек памяти по-прежнему может быть полезно в некоторых случаях, например при модульном тестировании. В таких случаях его можно включить, добавив следующую строку кода:

Platform.isMemoryLeakCheckerActive = true

Обратите внимание: включать средство проверки для среды выполнения приложения не рекомендуется.

Kotlin/JS

В Kotlin/JS в версии 1.5.0 появились эволюционные изменения. Мы продолжаем работу над переводом бэкенда компилятора JS на основе IR в стабильный статус и выпускаем другие обновления:

  • Обновление webpack до версии 5

  • Фреймворки и библиотеки для IR-компилятора

Обновление до webpack 5

Плагин Kotlin/JS для Gradle теперь использует webpack 5 для браузерных целей вместо webpack 4. Это крупное обновление webpack, которое содержит несовместимые изменения. Если вы используете пользовательскую конфигурацию webpack, ознакомьтесь с примечаниями к выпуску webpack 5.

Подробнее о сборке проектов Kotlin/JS с помощью webpack.

Фреймворки и библиотеки для IR-компилятора

IR-компилятор Kotlin/JS имеет статус альфа-версии. В будущем он может претерпеть несовместимые изменения и потребовать ручной миграции. Будем признательны за ваши отзывы на YouTrack.

Продолжая работу над бэкендом компилятора Kotlin/JS на основе IR, мы также помогаем авторам библиотек собирать проекты в режиме both. Это позволяет им создавать артефакты для обоих компиляторов Kotlin/JS и тем самым расширять экосистему нового компилятора.

Многие известные фреймворки и библиотеки уже доступны для IR-бэкенда: KVision, fritz2, doodle и другие. Если вы используете их в проекте, уже сейчас можно собрать его с IR-бэкендом и оценить преимущества.

Если вы разрабатываете собственную библиотеку, скомпилируйте её в режиме «both», чтобы клиенты также могли использовать её с новым компилятором.

Kotlin Multiplatform

В Kotlin 1.5.0 выбор тестовой зависимости для каждой платформы стал проще и теперь выполняется автоматически плагином Gradle.

В многоплатформенных проектах теперь доступен новый API для получения категории символа.

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

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

  • Стабильные беззнаковые целочисленные типы

  • Стабильный API для преобразования текста в верхний и нижний регистр, не зависящий от локали

  • Стабильный API преобразования Char в целое число

  • Стабильный API Path

  • Деление с округлением вниз и оператор mod

  • Изменения в API Duration

  • Новый API для получения категории символа теперь доступен в мультиплатформенном коде

  • Новая функция коллекций firstNotNullOf()

  • Строгая версия String?.toBoolean()

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

Стабильные беззнаковые целочисленные типы

Беззнаковые целочисленные типы UInt, ULong, UByte, UShort теперь имеют статус стабильных. То же относится к операциям с этими типами, их диапазонам и прогрессиям. Беззнаковые массивы и операции с ними остаются в статусе бета-версии.

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

Стабильный API для преобразования текста в верхний и нижний регистр, не зависящий от локали

В этом выпуске представлен новый API для преобразования текста в верхний и нижний регистр, не зависящий от локали. Он служит альтернативой функциям API toLowerCase(), toUpperCase(), capitalize() и decapitalize(), которые зависят от локали. Новый API помогает избежать ошибок, связанных с различными настройками локали.

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

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

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

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

    String.toUpperCase()

    String.uppercase()

    String.toLowerCase()

    String.lowercase()

    String.capitalize()

    String.replaceFirstChar { it.uppercase() }

    String.decapitalize()

    String.replaceFirstChar { it.lowercase() }

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

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

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

    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.

Старые функции API помечены как устаревшие и будут удалены в одном из будущих выпусков.

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

Стабильный API преобразования Char в целое число

Начиная с Kotlin 1.5.0 новые функции преобразования символов в коды и цифры имеют статус стабильных. Эти функции заменяют существующие функции API, которые часто путали с аналогичным преобразованием строки в Int.

Новый API устраняет эту путаницу в именовании, делая поведение кода более понятным и однозначным.

В этом выпуске представлены преобразования 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

Старые API преобразования, включая Number.toChar() с его реализациями (кроме Int.toChar()) и расширения Char для преобразования в числовой тип, например Char.toInt(), теперь объявлены устаревшими.

Подробнее об API преобразования Char в целое число см. в KEEP.

Стабильный API Path

Экспериментальный API Path с функциями-расширениями для java.nio.file.Path теперь имеет статус стабильного.

// construct path with the div (/) operator
val baseDir = Path("/base")
val subDir = baseDir / "subdirectory"

// list files in a directory
val kotlinFiles: List<Path> = Path("/home/user").listDirectoryEntries("*.kt")

Подробнее об API Path.

Деление с округлением вниз и оператор mod

В стандартную библиотеку добавлены новые операции для модульной арифметики:

  • floorDiv() возвращает результат деления с округлением вниз. Доступна для целочисленных типов.

  • mod() возвращает остаток от деления с округлением вниз (модуль). Доступна для всех числовых типов.

Эти операции похожи на существующие целочисленное деление и функцию rem() (или оператор %), но для отрицательных чисел они работают иначе:

  • a.floorDiv(b) отличается от обычного / тем, что floorDiv округляет результат вниз (к меньшему целому числу), тогда как / отбрасывает дробную часть, округляя результат до ближайшего к 0 целого числа.

  • a.mod(b) — это разность между a и a.floorDiv(b) * b. Оно равно нулю или имеет тот же знак, что и b, тогда как a % b может иметь другой знак.

fun main() {
//sampleStart
    println("Floored division -5/3: ${(-5).floorDiv(3)}")
    println( "Modulus: ${(-5).mod(3)}")
    
    println("Truncated division -5/3: ${-5 / 3}")
    println( "Remainder: ${-5 % 3}")
//sampleEnd    
}

Изменения в API Duration

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

Для представления длительности в разных единицах времени доступен экспериментальный класс Duration. В версии 1.5.0 в API Duration внесены следующие изменения:

  • Для внутреннего представления значений теперь используется Long вместо Double, что обеспечивает более высокую точность.

  • В Long появился новый API для преобразования длительности в определенную единицу времени. Он заменяет старый API, который работает со значениями Double и теперь объявлен устаревшим. Например, Duration.inWholeMinutes возвращает значение длительности в Long и заменяет Duration.inMinutes.

  • Добавлены новые функции-компаньоны для создания Duration из числа. Например, Duration.seconds(Int) создает объект Duration, представляющий целое число секунд. Старые свойства-расширения, такие как Int.seconds, теперь объявлены устаревшими.

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

@ExperimentalTime
fun main() {
//sampleStart
    val duration = Duration.milliseconds(120000)
    println("There are ${duration.inWholeSeconds} seconds in ${duration.inWholeMinutes} minutes")
//sampleEnd
}

Новый API для получения категории символа теперь доступен в мультиплатформенном коде

В Kotlin 1.5.0 представлен новый API для определения категории символа согласно Unicode в мультиплатформенных проектах. Несколько функций теперь доступны на всех платформах и в общем коде.

Функции для проверки того, является ли символ буквой или цифрой:

  • Char.isDigit()

  • Char.isLetter()

  • Char.isLetterOrDigit()

fun main() {
//sampleStart
    val chars = listOf('a', '1', '+')
    val (letterOrDigitList, notLetterOrDigitList) = chars.partition { it.isLetterOrDigit() }
    println(letterOrDigitList) // [a, 1]
    println(notLetterOrDigitList) // [+]
//sampleEnd    
}

Функции для проверки регистра символа:

  • Char.isLowerCase()

  • Char.isUpperCase()

  • Char.isTitleCase()

fun main() {
//sampleStart
    val chars = listOf('Dž', 'Lj', 'Nj', 'Dz', '1', 'A', 'a', '+')
    val (titleCases, notTitleCases) = chars.partition { it.isTitleCase() }
    println(titleCases) // [Dž, Lj, Nj, Dz]
    println(notTitleCases) // [1, A, a, +]
//sampleEnd    
}

Некоторые другие функции:

  • Char.isDefined()

  • Char.isISOControl()

Свойство Char.category и его тип возвращаемого значения — перечисление CharCategory, обозначающее общую категорию символа согласно Unicode, также теперь доступны в мультиплатформенных проектах.

Подробнее о символах.

Новая функция коллекций firstNotNullOf()

Новые функции firstNotNullOf() и firstNotNullOfOrNull() объединяют mapNotNull() с first() или firstOrNull(). Они преобразуют исходную коллекцию с помощью пользовательской функции-выборщика и возвращают первое ненулевое значение. Если такого значения нет, firstNotNullOf() выбрасывает исключение, а firstNotNullOfOrNull() возвращает null.

fun main() {
//sampleStart
    val data = listOf("Kotlin", "1.5")
    println(data.firstNotNullOf(String::toDoubleOrNull))
    println(data.firstNotNullOfOrNull(String::toIntOrNull))
//sampleEnd
}

Строгая версия String?.toBoolean()

Две новые функции добавляют чувствительные к регистру строгие версии существующей функции String?.toBoolean():

  • String.toBooleanStrict() выбрасывает исключение для всех входных данных, кроме литералов true и false.

  • String.toBooleanStrictOrNull() возвращает null для всех входных данных, кроме литералов true и false.

fun main() {
//sampleStart
    println("true".toBooleanStrict())
    println("1".toBooleanStrictOrNull())
    // println("1".toBooleanStrict()) // Exception
//sampleEnd    
}

Библиотека kotlin-test

В библиотеке kotlin-test появились новые возможности:

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

  • Автоматический выбор платформы тестирования для наборов исходного кода Kotlin/JVM

  • Обновления функций проверки

Упрощенное использование зависимостей для тестирования в мультиплатформенных проектах

Теперь можно использовать зависимость kotlin-test для добавления зависимостей для тестирования в набор исходного кода commonTest, а плагин Gradle определит соответствующие платформенные зависимости для каждого набора исходного кода тестов:

  • kotlin-test-junit для наборов исходного кода JVM; см. раздел автоматический выбор платформы тестирования для наборов исходного кода Kotlin/JVM

  • kotlin-test-js для наборов исходного кода Kotlin/JS

  • kotlin-test-common и kotlin-test-annotations-common для общих наборов исходного кода

  • Для наборов исходного кода Kotlin/Native дополнительный артефакт не требуется

Кроме того, зависимость kotlin-test можно использовать в любом общем или платформенном наборе исходного кода.

Существующая конфигурация kotlin-test с явно указанными зависимостями продолжит работать и в Gradle, и в Maven.

Подробнее о настройке зависимостей библиотек для тестирования.

Автоматический выбор платформы тестирования для наборов исходного кода Kotlin/JVM

Теперь плагин Gradle автоматически выбирает платформу тестирования и добавляет зависимость от нее. Достаточно добавить зависимость kotlin-test в общий набор исходного кода.

По умолчанию Gradle использует JUnit 4. Поэтому зависимость kotlin("test") разрешается в вариант для JUnit 4, а именно kotlin-test-junit:

kotlin {
    sourceSets {
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test")) // This brings the dependency
                                               // on JUnit 4 transitively
            }
        }
    }
}
kotlin {
    sourceSets {
        commonTest {
            dependencies {
                implementation kotlin("test") // This brings the dependency 
                                              // on JUnit 4 transitively
            }
        }
    }
}

JUnit 5 или TestNG можно выбрать, вызвав useJUnitPlatform() или useTestNG() в задаче тестирования:

tasks {
    test {
        // enable TestNG support
        useTestNG()
        // or
        // enable JUnit Platform (a.k.a. JUnit 5) support
        useJUnitPlatform()
    }
}

Чтобы отключить автоматический выбор платформы тестирования, добавьте строку kotlin.test.infer.jvm.variant=false в файл gradle.properties проекта.

Подробнее о настройке зависимостей библиотек для тестирования.

Обновления функций проверки

В этом выпуске появились новые функции проверки и улучшены существующие.

В библиотеке kotlin-test теперь доступны следующие возможности:

  • Проверка типа значения

    Для проверки типа значения можно использовать новые функции assertIs<T> и assertIsNot<T>:

    @Test
    fun testFunction() {
        val s: Any = "test"
        assertIs<String>(s)  // throws AssertionError mentioning the actual type of s if the assertion fails
        // can now print s.length because of contract in assertIs
        println("${s.length}")
    }
    

    Из-за стирания типов эта функция проверки в следующем примере проверяет только, является ли value типом List, но не проверяет, является ли это списком с определенным типом элементов String: assertIs<List<String>>(value).

  • Сравнение содержимого контейнеров для массивов, последовательностей и произвольных итерируемых объектов

    Добавлен новый набор перегруженных функций assertContentEquals() для сравнения содержимого разных коллекций, не реализующих структурное равенство:

    @Test
    fun test() {
        val expectedArray = arrayOf(1, 2, 3)
        val actualArray = Array(3) { it + 1 }
        assertContentEquals(expectedArray, actualArray)
    }
    
  • Новые перегрузки для assertEquals() и assertNotEquals() для чисел Double и Float

    Добавлены новые перегрузки функции assertEquals(), позволяющие сравнивать два числа Double или Float с абсолютной точностью. Значение точности задается третьим параметром функции:

     @Test
    fun test() {
        val x = sin(PI)
    
        // precision parameter
        val tolerance = 0.000001
    
        assertEquals(0.0, x, tolerance)
    }
    
  • Новые функции для проверки содержимого коллекций и элементов

    Теперь можно проверить, содержит ли коллекция или элемент заданное значение, с помощью функции assertContains(). Ее можно использовать с коллекциями Kotlin и элементами, для которых определен оператор contains(), например IntRange, String и другими:

    @Test
    fun test() {
        val sampleList = listOf<String>("sample", "sample2")
        val sampleString = "sample"
        assertContains(sampleList, sampleString)  // element in collection
        assertContains(sampleString, "amp")       // substring in string
    }
    
  • Функции assertTrue(), assertFalse(), expect() теперь являются inline-функциями

    Теперь их можно использовать как inline-функции, поэтому внутри лямбда-выражения можно вызывать приостанавливаемые функции:

    @Test
    fun test() = runBlocking<Unit> {
        val deferred = async { "Kotlin is nice" }
        assertTrue("Kotlin substring should be present") {
            deferred.await() .contains("Kotlin")
        }
    }
    

Библиотеки kotlinx

Одновременно с Kotlin 1.5.0 мы выпускаем новые версии библиотек kotlinx:

  • kotlinx.coroutines 1.5.0-RC

  • kotlinx.serialization 1.2.1

  • kotlinx-datetime 0.2.0

Coroutines 1.5.0-RC

Выпуск kotlinx.coroutines 1.5.0-RC включает:

  • Новый API каналов

  • Стабильные реактивные интеграции

  • И многое другое

Начиная с Kotlin 1.5.0, экспериментальные сопрограммы отключены, а флаг -Xcoroutines=experimental больше не поддерживается.

Подробнее см. в списке изменений и записи в блоге о выпуске kotlinx.coroutines 1.5.0.

Serialization 1.2.1

Выпуск kotlinx.serialization 1.2.1 включает:

  • Улучшение производительности сериализации JSON

  • Поддержка нескольких имен при сериализации JSON

  • Экспериментальная генерация схемы .proto из классов @Serializable

  • И многое другое

Подробнее см. в списке изменений и записи в блоге о выпуске kotlinx.serialization 1.2.1.

dateTime 0.2.0

Выпуск kotlinx-datetime 0.2.0 включает:

  • Объекты Datetime @Serializable

  • Унифицированный API для DateTimePeriod и DatePeriod

  • И многое другое

Подробнее см. в списке изменений и записи в блоге о выпуске kotlinx-datetime 0.2.0.

Переход на Kotlin 1.5.0

IntelliJ IDEA и Android Studio предложат обновить плагин Kotlin до версии 1.5.0, как только она станет доступна.

Чтобы перенести существующие проекты на Kotlin 1.5.0, просто измените версию Kotlin на 1.5.0 и повторно импортируйте проект Gradle или Maven. Узнайте, как обновить Kotlin до версии 1.5.0.

Чтобы начать новый проект на Kotlin 1.5.0, обновите плагин Kotlin и запустите мастер создания проектов через меню Файл | Создать | Проект.

Новый компилятор командной строки можно загрузить со страницы релиза на GitHub.

Kotlin 1.5.0 — это функциональный релиз, поэтому он может содержать несовместимые изменения языка. Подробный список таких изменений см. в руководстве по совместимости с Kotlin 1.5.

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

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

Spec-Zone.ru

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