Что нового в Kotlin 2.4.0
Вышла версия Kotlin 2.4.0! Вот основные нововведения:
Стандартная библиотека: стабилизация поддержки API UUID и поддержка проверки порядка сортировки
Kotlin/JVM: поддержка Java 26 и аннотации в метаданных, включенные по умолчанию
Kotlin/Native: поддержка пакетов Swift в качестве зависимостей, обновления экспорта Swift и включение CMS GC по умолчанию
Kotlin/Wasm: инкрементальная компиляция включена по умолчанию и добавлена поддержка модели компонентов WebAssembly
Kotlin/JS: поддержка экспорта value-классов и возможностей ES2015 при встраивании JS-кода
Gradle: совместимость с Gradle 9.5.0
Maven: автоматическое согласование целевых версий Java и JVM
Компилятор Kotlin: более последовательное поведение встроенных функций при компиляции
.klib
Обзор обновлений также представлен в этом видео:
Обновление до Kotlin 2.4.0
Последняя версия Kotlin включена в последние версии IntelliJ IDEA и Android Studio.
Чтобы обновиться до новой версии Kotlin, убедитесь, что ваша IDE обновлена до последней версии, и измените версию Kotlin на 2.4.0 в сценариях сборки.
Новые возможности
В предыдущих выпусках Kotlin несколько новых возможностей были представлены в статусе экспериментальных. Следующие возможности теперь получили статус стабильных в Kotlin 2.4.0, поэтому для их использования больше не требуется явно включать их:
Новые возможности
Улучшенные проверки неиспользуемых результатов функций высшего порядка
Новая аннотация
@IntroducedAtдля генерации перегрузок с учетом версии для необязательных параметровНовые резервные функции map для различения значений
nullи отсутствующих ключейЭкспорт Swift переходит в стадию Alpha с улучшенной поддержкой параллелизма
Язык
В Kotlin 2.4.0 контекстные параметры, явные резервные поля и возможности для мест применения аннотаций получили статус стабильных. В этом выпуске также добавлены явные контекстные аргументы для контекстных параметров.
Стабильные возможности
В Kotlin 2.2.0 и 2.3.0 было представлено несколько языковых возможностей в статусе экспериментальных. Рады сообщить, что в этом выпуске следующие языковые возможности получили статус стабильных:
Больше нет предупреждений об устаревании для последних сегментов импортов
В предыдущих версиях Kotlin при импорте устаревшего класса ошибка об устаревании сообщалась как в месте вызова, так и в самой директиве импорта. Поскольку подавить ошибки об устаревании в импортах невозможно, для обхода этой проблемы можно было подавлять сообщения об устаревании во всем файле или использовать импорты со звездочкой.
Поскольку в большинстве случаев сообщение об устаревании импортируемого символа не приносит пользы, Kotlin 2.4.0 не выдает предупреждение, если устаревший символ указан в последнем сегменте директивы импорта.
Дополнительную информацию см. в задаче KT-30155.
Явные контекстные аргументы для контекстных параметров
В Kotlin 2.4.0 добавлены явные контекстные аргументы для контекстных параметров.
В Kotlin 2.3.20 было изменено разрешение перегрузок для контекстных параметров. В результате вызовы перегруженных функций, отличающихся только контекстными параметрами, могут стать неоднозначными.
Теперь эту неоднозначность можно устранить, передав явный контекстный аргумент в месте вызова.
Пример:
class EmailSender
class SmsSender
context(emailSender: EmailSender)
fun sendNotification() {
println("Sent email notification")
}
context(smsSender: SmsSender)
fun sendNotification() {
println("Sent SMS notification")
}
context(defaultEmailSender: EmailSender, defaultSmsSender: SmsSender)
fun notifyUser() {
// Selects the overload with the EmailSender context parameter
sendNotification(emailSender = defaultEmailSender)
// Selects the overload with the SmsSender context parameter
sendNotification(smsSender = defaultSmsSender)
}
Также можно использовать явные контекстные аргументы вместо функции context(), чтобы уменьшить вложенность и сделать некоторые вызовы более понятными. Если одни и те же контекстные аргументы нужно использовать в нескольких вызовах, воспользуйтесь функцией context().
Эта возможность имеет статус экспериментальной. Чтобы включить ее, добавьте в файл сборки следующий параметр компилятора:
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xexplicit-context-arguments")
}
}
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xexplicit-context-arguments</arg>
</args>
</configuration>
</plugin>
</plugins>
</build>
Дополнительную информацию см. в KEEP этой возможности.
Поддержка литералов коллекций
В Kotlin 2.4.0 добавлена экспериментальная поддержка литералов коллекций. Теперь создавать коллекции можно проще и лаконичнее, используя скобки [].
Например:
fun main() {
// Mutable list with explicit type declaration
// val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
// Mutable list with brackets syntax
val shapes: MutableList<String> = ["triangle", "square", "circle"]
println(shapes)
// [triangle, square, circle]
}
Если компилятору недостаточно информации для определения типа коллекции, по умолчанию используется тип List:
fun main() {
val fruit = ["apple", "banana", "cherry"]
println(fruit)
// [apple, banana, cherry]
}
Также можно объявить собственные функции operator fun of, чтобы использовать синтаксис со скобками для своих типов. Например, если у вас есть следующий класс DoubleMatrix:
class DoubleMatrix(vararg val rows: Row) {
companion object {
operator fun of(vararg rows: Row) = DoubleMatrix(*rows)
}
class Row(vararg val elements: Double) {
companion object {
operator fun of(vararg elements: Double) = Row(*elements)
}
}
}
Создать экземпляр класса identityMatrix можно следующим образом:
fun main() {
val identityMatrix: DoubleMatrix = [
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
]
}
В этом примере компилятор преобразует вложенные литералы коллекций в вызовы соответствующих функций operator fun of. Компилятор рекурсивно разрешает эти вызовы и использует ожидаемые типы для выбора правильных перегрузок.
Эта возможность имеет статус экспериментальной. Чтобы включить ее, добавьте в файл сборки следующий параметр компилятора:
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xcollection-literals")
}
}
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xcollection-literals</arg>
</args>
</configuration>
</plugin>
</plugins>
</build>
Дополнительную информацию см. в KEEP этой возможности.
Улучшенные константы времени компиляции
В Kotlin 2.4.0 экспериментально улучшена работа с константами времени компиляции, благодаря чему поддержка числовых и строковых типов стала более последовательной и удобной. В частности, добавлена поддержка:
Операций с беззнаковыми типами.
Функций стандартной библиотеки для строк, таких как функции
.lowercase(),.uppercase()и.trim().Вычисление свойства
.nameконстант перечисления и интерфейсаKCallable.
Чтобы было понятно, какие функции вычисляются во время компиляции, в Kotlin 2.4.0 добавлена аннотация IntrinsicConstEvaluation. Некоторые функции вычисляются во время компиляции, но пока не имеют этой аннотации. В последующих выпусках ее добавят к остальным функциям. Список поддерживаемых функций см. в приложении KEEP.
Эта возможность имеет статус экспериментальной. Чтобы включить ее, добавьте в файл сборки следующий параметр компилятора:
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xintrinsic-const-evaluation")
}
}
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xintrinsic-const-evaluation</arg>
</args>
</configuration>
</plugin>
</plugins>
</build>
Дополнительную информацию см. в KEEP этой возможности.
Улучшенные проверки неиспользуемых результатов функций высшего порядка
В Kotlin 2.4.0 добавлен новый экспериментальный контракт returnsResultOf(), улучшающий проверку неиспользуемых возвращаемых значений.
Этот контракт позволяет проверке различать неиспользуемые результаты, которые можно игнорировать, и значимые неиспользуемые результаты функций высшего порядка, возвращающих результат лямбды, например функции области видимости let.
Чтобы воспользоваться этой возможностью, добавьте returnsResultOf() в контракт функции:
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
inline fun <T, R> T.customLet(block: (T) -> R): R {
contract {
returnsResultOf(block)
}
return block(this)
}
Вот пример использования пользовательской функции .customLet() с nullable-значением:
fun handleNullablePackageName(packageName: String?, builder: StringBuilder) {
// The checker doesn't report a warning
// because the return value of the append() function can be ignored
packageName?.customLet { builder.append(it) }
// The checker reports a warning because the returned string is unused
packageName?.customLet { "kotlin.$it" }
}
Проверка неиспользуемых возвращаемых значений имеет статус экспериментальной. Чтобы сообщать о неиспользуемых возвращаемых значениях, ее необходимо включить. Дополнительную информацию о включении и настройке проверки см. в разделе Проверка неиспользуемых возвращаемых значений.
Как включить
Контракт returnsResultOf() имеет статус экспериментального. Обратите внимание: его использование создает предварительные бинарные файлы, которые не могут быть прочитаны более ранними версиями компилятора Kotlin. Чтобы включить его, добавьте в файл сборки следующий параметр компилятора:
// build.gradle(.kts)
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xallow-returns-result-of")
}
}
<!-- pom.xml -->
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xallow-returns-result-of</arg>
</args>
</configuration>
</plugin>
</plugins>
</build>
Новая аннотация @IntroducedAt для генерации перегрузок с учетом версии для необязательных параметров
В Kotlin 2.4.0 добавлена аннотация @IntroducedAt для сохранения бинарной совместимости при добавлении новых необязательных параметров в опубликованные API.
Ранее добавление необязательных параметров в функцию часто требовало использования @JvmOverloads, что могло создавать больше перегрузок, чем необходимо. Другой способ сохранить бинарную совместимость — оставить старые сигнатуры в виде скрытых устаревших перегрузок.
С помощью аннотации @IntroducedAt можно пометить новые необязательные параметры версией, в которой они были добавлены. Компилятор использует эту информацию для автоматической генерации соответствующих скрытых перегрузок.
Эта аннотация имеет статус экспериментальной. Чтобы включить ее, используйте аннотацию @OptIn(ExperimentalVersionOverloading::class).
Пример:
@OptIn(ExperimentalVersionOverloading::class)
fun Button(
label: String = "",
color: Color = DefaultColor,
@IntroducedAt("1.1") borderColor: Color = DefaultBorderColor,
@IntroducedAt("1.2") borderStyle: Style = DefaultBorderStyle,
@IntroducedAt("1.2") borderWidth: Int = 1,
onClick: () -> Unit
) {
// Function body
}
В этом примере компилятор генерирует скрытые перегрузки функции Button() для более ранних версий.
Поскольку и @IntroducedAt, и @JvmOverloads генерируют перегрузки, их совместное использование может привести к конфликтующим перегрузкам. Если используются обе аннотации, компилятор выдает предупреждение. При подавлении предупреждения компилятор отдает приоритет перегрузкам, сгенерированным на основе аннотации @IntroducedAt.
Стандартная библиотека
В Kotlin 2.4.0 стабилизирована поддержка UUID в общей стандартной библиотеке Kotlin. Также добавлены новые функции расширения для преобразования беззнаковых целых чисел в BigInteger на JVM и поддержка проверки порядка сортировки.
Стабильный API UUID в общей стандартной библиотеке Kotlin
В Kotlin 2.0.20 был добавлен класс для генерации UUID (универсальных уникальных идентификаторов), а также поддержка преобразования между UUID Kotlin и Java. В последующих выпусках эта экспериментальная возможность постепенно улучшалась: была добавлена поддержка:
В Kotlin 2.4.0 API kotlin.uuid.Uuid получает статус стабильного. Исключение составляют только функции генерации UUID версий V4 и V7: они остаются экспериментальными, и для их использования по-прежнему требуется явное включение.
Подробнее о работе с UUID см. в разделе UUID.
Поддержка проверки порядка сортировки
В Kotlin 2.4.0 добавлены новые функции расширения для проверки порядка сортировки элементов в итерируемых объектах, массивах и последовательностях.
Добавлены следующие функции расширения:
.isSorted().isSortedDescending().isSortedWith(comparator).isSortedBy(selector).isSortedByDescending(selector)
Эти функции расширения позволяют проверить, отсортированы ли элементы, не сортируя их повторно и не создавая собственных вспомогательных функций. Они возвращают true, если элементы упорядочены указанным образом или их меньше двух, и false в противном случае. Функции завершают работу сразу после обнаружения пары элементов, нарушающей порядок, поэтому они эффективны для больших наборов данных.
Пример проверки порядка сортировки с помощью функций .isSorted() и .isSortedBy():
data class User(val name: String, val age: Int)
fun main() {
val numbers = listOf(1, 2, 3, 4)
println(numbers.isSorted())
// true
val users = listOf(
User("Alice", 24),
User("Bob", 31),
User("Charlie", 29),
)
println(users.isSortedBy(User::age))
// false
}
Новый API для преобразования беззнаковых целых чисел в BigInteger на JVM
В Kotlin 2.4.0 на JVM добавлены функции расширения UInt.toBigInteger() и ULong.toBigInteger().
Ранее для преобразования значений UInt и ULong в BigInteger приходилось использовать обходные пути со строками или собственную логику преобразования. Начиная с Kotlin 2.4.0, для прямого преобразования значений беззнаковых целых чисел в BigInteger можно использовать .toBigInteger().
Пример:
fun main() {
//sampleStart
val unsignedLong = Long.MAX_VALUE.toULong() + 1uL
val unsignedInt = UInt.MAX_VALUE
println(unsignedLong.toBigInteger())
// 9223372036854775808
println(unsignedInt.toBigInteger())
// 4294967295
//sampleEnd
}
Новые резервные функции map для различения значений null и отсутствующих ключей
В Kotlin 2.4.0 добавлены новые варианты существующих .getOrElse() и .getOrPut() функций расширения для map, предназначенные для map с nullable-значениями. Эти функции извлекают значение по ключу или используют значение по умолчанию в качестве резервного. Для map с nullable-значениями новые варианты позволяют выбрать, будет ли сохраненное значение null трактоваться как отсутствующий ключ или как существующее значение; этот выбор явно отражен в именах функций.
Новые функции расширения включают:
.getOrElseIfNull(key, defaultValue)и.getOrPutIfNull(key, defaultValue), которые возвращают значение по умолчанию, если ключ отсутствует или содержит значениеnull, подобно существующим функциям.getOrElse()и.getOrPut()..getOrElseIfMissing(key, defaultValue)и.getOrPutIfMissing(key, defaultValue), которые возвращают значение по умолчанию только в том случае, если map не содержит указанный ключ.
Эти API имеют статус экспериментальных и требуют явного включения с помощью аннотации @OptIn(ExperimentalStdlibApi::class).
Вот пример, демонстрирующий разницу между .getOrPutIfNull() и .getOrPutIfMissing(), если ключ существует и имеет значение null:
@OptIn(ExperimentalStdlibApi::class)
fun main() {
val mapForNull = mutableMapOf<String, String?>("user" to null)
val mapForMissing = mutableMapOf<String, String?>("user" to null)
// Replaces the value if "user" has a null value
mapForNull.getOrPutIfNull("user") { "default_user" }
println(mapForNull)
// {user=default_user}
// Keeps the null value because "user" exists in the map
mapForMissing.getOrPutIfMissing("user") { "default_user" }
println(mapForMissing)
// {user=null}
}
Функции .getOrElseIfMissing() и .getOrPutIfMissing() можно также использовать для кэшей, в которых хранятся nullable-значения. Если defaultValue возвращает null, map сохраняет его и не вызывает defaultValue повторно для того же ключа.
Пример:
data class Response(val body: String)
class Service {
var queryCount = 0
fun query(key: String): Response? {
queryCount += 1
return null
}
}
//sampleStart
@OptIn(ExperimentalStdlibApi::class)
fun main() {
val service = Service()
val cache = mutableMapOf<String, Response?>()
fun getCachedResponseOrQuery(key: String): Response? =
cache.getOrPutIfMissing(key) { service.query(key) }
// Stores null because the cache doesn't contain "user"
getCachedResponseOrQuery("user")
println(cache)
// {user=null}
// Uses the cached null and doesn't query the service again
getCachedResponseOrQuery("user")
println(service.queryCount)
// 1
}
//sampleEnd
Будем рады вашим отзывам в YouTrack.
Kotlin/JVM
Kotlin 2.4.0 поддерживает новую версию Java и включает аннотации в метаданные по умолчанию.
Поддержка Java 26
Начиная с Kotlin 2.4.0, компилятор может генерировать классы, содержащие байт-код Java 26.
Аннотации в метаданных включены по умолчанию
Библиотека Kotlin Metadata JVM в Kotlin 2.2.0 получила поддержку чтения аннотаций, сохранённых в метаданных Kotlin. Благодаря этой поддержке компилятор Kotlin записывает аннотации в метаданные вместе с байт-кодом JVM, делая их доступными для библиотеки Kotlin Metadata JVM. В результате обработчики аннотаций и другие инструменты могут распознавать эти аннотации и работать с ними на уровне метаданных, не используя рефлексию и не изменяя исходный код.
В Kotlin 2.4.0 эта поддержка включена по умолчанию.
Kotlin/Native
Начиная с Kotlin 2.4.0, экспорт Swift переходит на стадию Alpha. В этом выпуске также появилась поддержка импорта пакетов Swift, Xcode 26.4, а также улучшения потребления памяти и сборки мусора.
Параллельная маркировка в сборщике мусора включена по умолчанию
В Kotlin 2.0.20 команда Kotlin добавила экспериментальную поддержку сборщика мусора с параллельной маркировкой и очисткой (CMS GC). После обработки отзывов пользователей и исправления регрессий мы готовы включить CMS по умолчанию, начиная с Kotlin 2.4.0.
В предыдущей конфигурации сборщика мусора — параллельной маркировке и параллельной очистке (PMCS) — потоки приложения приходилось приостанавливать, пока GC помечал объекты в куче. В отличие от неё, CMS позволяет выполнять этап маркировки параллельно с потоками приложения.
Это значительно сокращает длительность пауз GC и повышает отзывчивость приложений, что важно для производительности приложений, критичных к задержкам. Эффективность CMS уже подтвердилась в тестах производительности приложений с интерфейсом, созданных с помощью Compose Multiplatform.
Если возникнут проблемы, можно вернуться к PMCS. Для этого задайте следующий параметр двоичного файла в файле gradle.properties:
kotlin.native.binary.gc=pmcs
Дополнительную информацию о сборщике мусора Kotlin/Native см. в нашей документации.
Снижение потребления памяти при анализе девиртуализации
Ранее анализ девиртуализации был одним из самых ресурсоёмких этапов компилятора Kotlin/Native. В частности, задача link release потребляла слишком много памяти, особенно в крупных проектах.
В Kotlin 2.4.0 появились улучшения, помогающие снизить пиковое потребление памяти во время задач link release.
Согласно результатам тестов производительности одного из пользователей EAP, улучшенный анализ девиртуализации вдвое сократил потребление памяти задачами link release, сэкономив не менее 13 ГБ.
Поддержка Xcode 26.4
Начиная с Kotlin 2.4.0, компилятор Kotlin/Native поддерживает Xcode 26.4 — одну из последних стабильных версий Xcode.
Теперь вы можете обновить Xcode и получить доступ к новейшим API, чтобы продолжить работу над проектами Kotlin для операционных систем Apple.
Обновление LLVM до версии 21
В Kotlin 2.4.0 мы обновили LLVM с версии 19 до версии 21. Новая версия содержит улучшения производительности и помогает поддерживать компилятор Kotlin/Native в актуальном состоянии.
Это обновление не должно повлиять на ваш код, но если вы столкнётесь с проблемами, сообщите о них в наш трекер ошибок.
Изменения в поддержке целевых платформ Apple
В Kotlin 2.4.0 повышены минимальные версии целевых платформ Apple, поддерживаемые по умолчанию:
Для iOS и tvOS — с 14.0 до 15.0.
Для macOS — с 11.0 до 12.0.
Для watchOS — с 7.0 до 8.0.
Если в проекте нужно поддерживать версию ниже указанной по умолчанию, используйте параметр freeCompilerArgs в файле сборки:
kotlin {
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>().configureEach {
binaries.configureEach {
freeCompilerArgs += "-Xoverride-konan-properties=minVersion.ios=14.0"
freeCompilerArgs += "-Xoverride-konan-properties=minVersion.macos=11.0"
freeCompilerArgs += "-Xoverride-konan-properties=minVersion.tvos=14.0"
freeCompilerArgs += "-Xoverride-konan-properties=minVersion.watchos=7.0"
}
}
}
Экспорт Swift переходит на стадию Alpha с улучшенной поддержкой конкурентности
Начиная с Kotlin 2.4.0, совместимость Kotlin со Swift посредством экспорта Swift официально переходит на стадию Alpha! В этом выпуске значительно улучшена поддержка конкурентности: в экспорт Swift добавлены встроенная структурированная конкурентность и возможность экспортировать потоки kotlinx.coroutines в Swift.
Поддержка структурированной конкурентности
Теперь можно без проблем вызывать приостанавливающийся код Kotlin из Swift. Функции Kotlin suspend и функциональные типы с модификатором suspend экспортируются как идиоматичные аналоги async в Swift:
// Kotlin
suspend fun hello(): String {
delay(1000)
return "Hello Swift! This is Kotlin."
}
// Swift let msg = try await hello()
Экспорт типов Flow в Swift
Это обновление также добавляет поддержку экспорта потоков kotlinx.coroutines в Swift. Потоки в kotlinx.coroutines представляют собой асинхронный поток данных, который можно генерировать и обрабатывать параллельно. Их часто используют в реактивном программировании, например, чтобы получать обновления базы данных, сетевые запросы или события пользовательского интерфейса.
Раньше единственным способом предоставить интерфейс Flow из kotlinx.coroutines.flow для Swift были сторонние решения. Теперь потоки можно сразу экспортировать в идиоматичный аналог Swift: AsyncSequence.
Эта функция включена по умолчанию. В Swift можно экспортировать любой общедоступный API с типом Flow, сохранив информацию о типах. Например:
// Kotlin
// Type String is preserved when exporting Flow
fun flowOfStrings(): Flow<String> = flowOf("hello", "any", "world")
// Swift
var actual: [String] = []
// Type String is correctly inferred from Kotlin
for try await element in flowOfStrings().asAsyncSequence() {
actual.append(element)
}
Дополнительную информацию об экспорте Swift см. в нашей документации.
Импорт пакетов Swift
Теперь проекты Kotlin Multiplatform могут указывать пакеты Swift в качестве зависимостей приложения iOS в конфигурации Gradle:
// build.gradle.kts
kotlin {
swiftPMDependencies {
swiftPackage(
url = url("https://github.com/firebase/firebase-ios-sdk.git"),
version = from("12.11.0"),
products = listOf(
product("FirebaseAI"),
product("FirebaseAnalytics"),
...
}
Примеры работающего кода и более подробную информацию см. в разделе Импорт SwiftPM.
Если проект использует зависимости CocoaPods, можно перенести текущую конфигурацию на пакеты Swift. Инструменты KMP поддерживают такой сценарий и помогают автоматически перенастроить проект. Подробнее см. в нашем руководстве по миграции с CocoaPods.
Kotlin/Wasm
В Kotlin 2.4.0 инкрементальная компиляция для Kotlin/Wasm включена по умолчанию, а также добавлена поддержка компонентной модели WebAssembly.
Инкрементальная компиляция включена по умолчанию
Инкрементальная компиляция появилась в Kotlin/Wasm в Kotlin 2.1.0. Начиная с Kotlin 2.4.0, она получила статус Stable и включена по умолчанию. Благодаря этой функции компилятор пересобирает только файлы, на которые повлияли последние изменения, что значительно сокращает время сборки.
Чтобы отключить инкрементальную компиляцию, добавьте следующую строку в файл local.properties или gradle.properties вашего проекта:
# gradle.properties kotlin.incremental.wasm=false
Если вы столкнётесь с проблемами, сообщите о них в YouTrack
Улучшенное отображение внутренних переменных в Chrome DevTools
В Kotlin 2.4.0 улучшена отладка Kotlin/Wasm в Chrome DevTools: временные, синтетические и внутренние переменные теперь проще отличить от переменных, определённых пользователем.
Компилятор Kotlin и плагины компилятора, например Compose, могут генерировать такие переменные. Теперь по умолчанию для них используется префикс ~, поэтому они группируются вместе и перемещаются в конец списка переменных, который Chrome DevTools сортирует по имени.
Поддержка компонентной модели WebAssembly
В Kotlin 2.4.0 Kotlin/Wasm делает ещё один шаг вперёд: добавлена экспериментальная поддержка компонентной модели WebAssembly. В предложении описан способ создания компонентов из модулей Wasm с помощью стандартизированных интерфейсов и типов. Такой подход позволяет Wasm перейти от низкоуровневого формата двоичных инструкций к системе для объединения повторно используемых компонентов, не зависящих от языка программирования. Благодаря этому Kotlin/Wasm выходит за пределы браузера. Например, Kotlin и WebAssembly хорошо подходят для приложений Function-as-a-Service (FaaS), также известных как бессерверные приложения.
Чтобы попробовать эту функцию, ознакомьтесь с простым сервером, созданным с помощью wasi:http.

Оставьте отзыв в YouTrack.
Kotlin/JS
В Kotlin 2.4.0 дополнительно улучшен экспорт в JavaScript/TypeScript: теперь поддерживается экспорт классов-значений, интерфейсов и вариативности типов, а также функций ES2015 при встраивании JS-кода.
Поддержка экспорта классов-значений в JavaScript/TypeScript
Раньше в JavaScript/TypeScript можно было экспортировать только обычные классы Kotlin. В Kotlin 2.4.0 это ограничение снято. Теперь встраиваемые классы-значения Kotlin можно экспортировать как обычные классы TypeScript.
Чтобы экспортировать класс-значение, пометьте его аннотацией @JsExport в коде Kotlin:
// Kotlin
@JsExport
@JvmInline
value class Email(val address: String) {
init { require(address.contains("@")) { "Invalid email" } }
}
@JsExport
class AuthService {
suspend fun login(email: Email): String = ...
}
В TypeScript он выглядит как обычный класс:
// TypeScript
import { AuthService, Email } from "..."
const auth = new AuthService();
console.log(await auth.login(new Email("jane@example.com")));
// "Welcome, jane@example.com!"
console.log(await auth.login(new Email("not-an-email")));
// "Invalid email"
Дополнительную информацию см. в разделе аннотация @JsExport.
Поддержка функций ES2015 при встраивании JS-кода
Начиная с Kotlin 2.4.0, встраивание кода JavaScript полностью поддерживает функции ES2015.
Это полезно для взаимодействия со сторонними библиотеками, а также для непосредственного управления автоматической генерацией кода приложения.
Теперь в вызовах js() можно использовать современные функции JS, в том числе:
объявления переменных
constиletклассы ES
генераторы
лямбды (стрелочные функции)
операторы spread и rest
шаблонные строки
Обратите внимание: параметр функции js() должен быть строковой константой, поскольку он анализируется во время компиляции и преобразуется в код JavaScript «как есть». Например, чтобы встроить оператор spread, используйте:
fun spreadExample(): dynamic = js("""
const add = (a, b, c) => a + b + c;
const nums = [1, 2, 3];
const sum = add(...nums);
const a = [1, 2, 3];
const b = [...a, 4, 5, 6];
return { sum, b: b };
""")
Дополнительную информацию о встраивании кода JavaScript см. в нашей документации.
Сохранение вариативности типов при экспорте в TypeScript
Ранее при экспорте типов в TypeScript терялась информация о вариативности обобщённых типов.
В Kotlin 2.4.0 аннотация вариативности сохраняется при экспорте и сопоставляется с аннотациями вариативности TypeScript.
В коде Kotlin задайте вариативность параметров обобщённого типа:
// Kotlin
// 'out' signals covariance (the interface only produces T)
interface Producer<out T> {
fun produce(): T
}
// 'in' signals contravariance (the interface only consumes T)
interface Consumer<in T> {
fun consume(item: T)
}
В Kotlin 2.4.0 ключевые слова in и out сохраняются в сгенерированном коде TypeScript:
// Generated .d.ts
export interface Producer<out T> {
produce(): T;
}
export interface Consumer<in T> {
consume(item: T): void;
}
Улучшенный экспорт интерфейсов в JavaScript/TypeScript
В Kotlin 2.4.0 экспорт интерфейсов Kotlin в JavaScript/TypeScript стал удобнее.
Новая аннотация @JsNoRuntime удаляет ранее необходимые метаданные для реализации интерфейсов Kotlin и позволяет напрямую сопоставлять их с обычными интерфейсами TypeScript, подобно внешним интерфейсам, которые и так ведут себя таким образом по умолчанию.
Чтобы экспортировать интерфейс Kotlin, например в проекте Kotlin Multiplatform, пометьте его аннотацией @JsNoRuntime в общем коде:
// commonMain
import kotlin.js.JsNoRuntime
@JsNoRuntime
expect interface DataProcessor {
fun process(data: String): Int
}
Затем предоставьте фактическую реализацию в исходном коде для JS:
// jsMain
@JsNoRuntime
actual interface DataProcessor {
actual fun process(data: String)
}
Поскольку необходимые для реализации интерфейсов Kotlin метаданные удалены, интерфейс сопоставляется с обычным интерфейсом TypeScript:
// Generated .d.ts
export interface DataProcessor {
process(data: string): void;
}
Аннотацию @JsNoRuntime можно использовать только со стандартными интерфейсами, чтобы TypeScript мог воспринимать интерфейсы Kotlin как обычные интерфейсы TypeScript. Поэтому следующие операции запрещены:
Проверки типов
isиas.Ссылки на классы с использованием синтаксиса
::class.Передача интерфейса в качестве реифицированного аргумента типа.
Снятие ограничений на экспорт интерфейсов
В Kotlin 2.4.0 сделан ещё один шаг к стабилизации @JsExport: улучшен экспорт интерфейсов Kotlin.
Теперь можно экспортировать интерфейсы Kotlin с вложенными классами и именованными объектами-компаньонами:
@JsExport
interface Identity {
class Metadata(val tag: String)
companion object Registry {
val defaultTag = "GUEST"
}
}
Дополнительную информацию см. в разделе аннотация @JsExport.
Gradle
Kotlin 2.4.0 полностью совместим с Gradle версий от 7.6.3 до 9.5.0. Также можно использовать версии Gradle вплоть до последнего выпуска. Однако учтите, что это может привести к предупреждениям об устаревших функциях, а некоторые новые возможности Gradle могут работать некорректно. В Kotlin 2.4.0 также появились улучшения: единые имена модулей по умолчанию для всех платформ и вывод сообщений компилятора Kotlin/JVM в Problems API.
Минимальная поддерживаемая версия AGP повышена до 8.5.2
Начиная с Kotlin 2.4.0, минимальная поддерживаемая версия плагина Android Gradle — 8.5.2.
Единые имена модулей для всех платформ
До Kotlin 2.4.0 имена модулей по умолчанию различались на разных платформах. Это несоответствие могло приводить к конфликтам имён и проблемам разрешения зависимостей. В Kotlin 2.4.0 для всех платформ стандартизированы имена по умолчанию: {group}:{project_name}.
Если нужно вернуть для модуля JVM прежнее имя, добавьте следующий код в файл build.gradle.kts проекта Kotlin/JVM:
kotlin {
compilerOptions.moduleName(project.name)
}
Для мультиплатформенного проекта:
kotlin {
jvm {
compilerOptions.moduleName(project.name)
}
}
Сообщения компилятора Kotlin/JVM записываются в Problems API
В Kotlin 2.2.0 плагин Kotlin Gradle (KGP) начал передавать диагностические сообщения в Problems API Gradle, чтобы обеспечить единообразную работу как в интерфейсе командной строки Gradle, так и в IntelliJ IDEA.
В Kotlin 2.4.0 плагин также записывает в Problems API сообщения компилятора Kotlin/JVM, приближая API к роли единого источника для всех журналов и сообщений.
Maven
В Kotlin 2.4.0 настройка проекта стала ещё проще благодаря поддержке Maven Toolchains и автоматическому согласованию целевых версий Java и JVM.
Автоматическое согласование целевых версий Java и JVM
Чтобы упростить настройку проекта и предотвратить проблемы совместимости, плагин Kotlin Maven теперь автоматически согласует целевую версию JVM с версией компилятора Java, настроенной в проекте.
Это гарантирует, что компиляторы Kotlin и Maven генерируют байт-код одной версии, предотвращая проблемы, при которых байт-код Kotlin несовместим с остальной частью проекта или предполагаемой средой развёртывания.
Если параметр <extensions> включён, задавать параметры kotlin.compiler.jvmTarget или kotlin.compiler.jdkRelease не нужно. Если ни один из них не задан, плагин Kotlin Maven автоматически определяет целевую версию JVM в следующем порядке:
-
Как версия
maven.compiler.release, заданная в свойстве проекта или в конфигурацииmaven-compiler-plugin.В этом случае для компилятора Kotlin задаются параметры компилятора
jvmTargetиjdkRelease, ограничивающие API определённой версией JDK. -
Как версия
maven.compiler.target, если версия выпуска Maven не задана. Целевую версию компилятора можно определить в свойстве проекта или в конфигурацииmaven-compiler-plugin.В этом случае задаётся только параметр Kotlin
jvmTarget, и API не ограничивается определённой версией JDK.
Это значительно упрощает настройку проекта Kotlin, поэтому файл pom.xml может выглядеть так:
<properties>
<maven.compiler.release>17</maven.compiler.release>
<kotlin.version>2.4.20</kotlin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
Во время сборки плагин выводит сообщение примерно такого вида:
[INFO] Using jvmTarget=17 (derived from maven.compiler.release=17)
Дополнительную информацию об автоматической настройке проекта см. в нашей документации.
Поддержка Maven Toolchains
В Kotlin 2.4.0 в плагин Kotlin Maven добавлена поддержка Maven Toolchains.
Эта функция помогает управлять версией JDK при сборке. С помощью Maven Toolchains можно указать версию JDK для компиляции Kotlin независимо от версии JVM, на которой работает Maven (она задаётся в JAVA_HOME). Если в сборке настроен maven-toolchains-plugin, плагин Kotlin Maven автоматически использует выбранную цепочку инструментов JDK, как это делают плагин компилятора Maven и другие плагины Maven. Это позволяет настроить одну цепочку инструментов для управления JDK, используемой всеми плагинами сборки, включая компиляцию Kotlin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>21</version>
</jdk>
</toolchains>
</configuration>
</plugin>
Учитывайте приоритет различных способов задания версии JDK:
jdkHomeв конфигурацииkotlin-maven-plugin. Явно заданный параметрjdkHomeвсегда имеет приоритет над версией из цепочки инструментов.Версия JDK в
maven-toolchains-plugin. Версия JDK, заданная с помощью Maven Toolchains, имеет приоритет над версией JDK, заданной в путиJAVA_HOME.Путь
JAVA_HOME.
Также можно использовать параметр <jdkToolchain>, специфичный для плагина, чтобы напрямую задать версию JDK в цепочке инструментов kotlin-maven-plugin. В отличие от использования maven-toolchains-plugin, этот параметр влияет только на компиляцию Kotlin и не затрагивает другие плагины сборки.
Дополнительную информацию о настройке проектов Kotlin Maven см. в нашей документации.
API средств сборки
В Kotlin 2.4.0 в API средств сборки (BTA) появилось несколько улучшений. BTA:
Добавляет новые типобезопасные абстракции для большинства общих параметров компилятора и параметров компилятора JVM. Теперь BTA обрабатывает их формат вместо клиента, снижая риск ошибок и предоставляя дополнительную поддержку. Это изменение обратно совместимо во время выполнения, но может нарушить совместимость исходного кода.
Теперь отслеживает изменения, не связанные с исходным кодом, при инкрементальной компиляции, например настройку другой версии Kotlin или изменение параметров компилятора. Системы сборки могут управлять этим поведением с помощью параметра
BaseIncrementalCompilationConfiguration.TRACK_CONFIGURATION_INPUTS.Поддерживает проверку двоичной совместимости с помощью
AbiValidationToolchain, упрощая добавление этой функциональности в другие системы сборки.Добавляет новую функцию, позволяющую системам сборки настраивать отображение сообщений компилятора с помощью интерфейса
CompilerMessageRendererи построителяJvmCompilationOperation.-
Добавляет новые параметры для настройки журналирования демона Kotlin:
LOGS_PATH— каталог для файлов журнала демона.LOGS_FILE_SIZE_LIMIT— максимальный размер файла журнала в байтах.LOGS_FILE_COUNT_LIMIT— максимальное количество сохраняемых файлов журнала.
По умолчанию ограничения задаются значением, зависящим от версии компилятора Kotlin. Чтобы снять ограничение, средства сборки должны задать для параметра значение
null.Системы сборки могут задать этот параметр при настройке политики выполнения:
val executionPolicy = kotlinToolchains.daemonExecutionPolicy { set(ExecutionPolicy.WithDaemon.LOGS_PATH, Paths("/var/log/kotlin-daemon")) set(ExecutionPolicy.WithDaemon.LOGS_FILE_SIZE_LIMIT, 10_485_760L) set(ExecutionPolicy.WithDaemon.LOGS_FILE_COUNT_LIMIT, 10) }
Компилятор Kotlin
Kotlin 2.4.0 обеспечивает более согласованное поведение встроенных функций, объявленных в одном модуле, во время компиляции .klib.
Согласованное встраивание функций внутри модуля во время компиляции klib
Ранее встраивание функций вело себя по-разному на разных платформах Kotlin. Команда JetBrains работает над тем, чтобы унифицировать его на всех поддерживаемых платформах и обеспечить одинаковые гарантии совместимости.
На Kotlin/JVM встраивание функций происходит во время компиляции. Поэтому, когда исходный код Kotlin компилируется компилятором Kotlin/JVM, в полученных файлах классов нет вызовов встроенных функций в байт-коде, поскольку тела встроенных функций вставляются в места их вызова, а значит, их поведение фиксируется во время компиляции.
Напротив, в Kotlin/Native, Kotlin/JS и Kotlin/Wasm встраивание функций происходило не при компиляции исходного кода в klib, а только при создании бинарных файлов. В результате поведение встроенных функций не фиксировалось во время компиляции .klib, а библиотеки .klib не обеспечивали такие же гарантии совместимости для встроенных функций, как Kotlin/JVM.
Kotlin 2.4.0 делает первый шаг к унификации поведения встроенных функций, включая встраивание внутри модуля при создании артефактов .klib:
// Existing logging.klib library
inline fun logDebug(message: String) {
println("[DEBUG] $message")
}
// Currently compiled App module
inline fun greetUser(name: String) {
println("Hello, $name!")
}
fun main() {
logDebug("App started") // Not inlined: declared in another module
greetUser("Alice") // Inlined: declared in the same module
}
При компиляции в .klib код выглядит примерно так:
// Pseudocode
fun main() {
logDebug("App started") // Not inlined, declared in another module
val tmp0 = "Alice"
println("Hello, $tmp0!") // Inlined from greetUser()
}
Это означает, что во время компиляции .klib встраиваются только встроенные функции, объявленные в том же модуле. Остальные функции, в данном случае, встраиваются при создании бинарных файлов для конкретной платформы.
Как включить
Начиная с версии 2.4.0, внутримодульное встраивание по умолчанию включено для Kotlin/Native, Kotlin/JS и Kotlin/Wasm.
Если эта функция вызывает неожиданные проблемы, ее можно отключить с помощью следующего параметра компилятора в командной строке:
-Xklib-ir-inliner=disabled
Следующий шаг — включить встраивание между модулями, чтобы все встроенные функции в проекте встраивались согласованно. Это изменение запланировано для будущих выпусков Kotlin, но вы уже можете попробовать его с помощью следующего параметра компилятора в командной строке:
-Xklib-ir-inliner=full
Поделитесь отзывом и сообщите о проблемах в YouTrack.
Согласованная частичная компоновка библиотек в компиляторах Kotlin
В Kotlin 1.9.0 частичная компоновка библиотек была включена по умолчанию и в компиляторе Kotlin/Native, и в компиляторе Kotlin/JS, а в Kotlin 2.0.0 к ним присоединился Kotlin/Wasm. Эта функция позволяет компиляторам обрабатывать проблемы компоновки в библиотеках Kotlin так же, как в Kotlin/JVM.
С тех пор мы не получали отрицательных отзывов и не замечали, чтобы пользователи отключали частичную компоновку в своих проектах. Поэтому начиная с Kotlin 2.4.0 частичная компоновка всегда включена, а параметр компилятора -Xpartial-linkage объявлен устаревшим.
Уровень журнала по умолчанию для всех компиляторов Kotlin — SILENT. Проблемы компоновки не сообщаются во время компиляции. Чтобы изменить это поведение в проектах, задайте параметр компилятора -Xpartial-linkage-loglevel в файле сборки:
// build.gradle.kts
kotlin {
macosX64("native") {
binaries.executable()
compilations.configureEach {
compilerOptions.configure {
// To report linkage issues with the “info” log level:
freeCompilerArgs.add("-Xpartial-linkage-loglevel=INFO")
// To report issues as errors:
freeCompilerArgs.add("-Xpartial-linkage-loglevel=ERROR")
}
}
}
}
INFOсообщает о проблемах компоновки с уровнем журнала «info».WARNINGсообщает о предупреждениях во время компиляции и записывает их в журналы компиляции.ERRORпозволяет завершить компиляцию с ошибкой при наличии проблем компоновки и сообщает об ошибках в журналах компиляции. Используйте этот параметр, чтобы подробнее изучить проблемы компоновки.
Если у вас возникли проблемы с этой функцией, сообщите о них в наш трекер задач.
Плагины компилятора Kotlin
В Kotlin 2.4.0 также появились заметные обновления плагинов компилятора Kotlin. Теперь плагин kapt может исключать ненужные процессоры аннотаций из пути классов компиляции, а плагин Power-assert предлагает упрощенную настройку с помощью новой библиотеки времени выполнения.
kapt: исключение процессоров аннотаций из пути классов компиляции
В Kotlin 2.4.0 добавлена поддержка параметра конфигурации includeCompileClasspath для обнаружения процессоров аннотаций, аналогичная поддержке в плагине Kotlin Gradle. Новый параметр позволяет исключать ненужные процессоры аннотаций из пути классов компиляции.
Чтобы настроить это в файле сборки, задайте для параметра includeCompileClasspath значение false в разделе <execution> плагина kapt:
<execution>
<id>kapt</id>
<goals><goal>kapt</goal></goals>
<configuration>
<!-- Add new option -->
<includeCompileClasspath>false</includeCompileClasspath>
<sourceDirs>...</sourceDirs>
<annotationProcessorPaths>...</annotationProcessorPaths>
</configuration>
</execution>
Кроме того, можно сделать то же самое с помощью kapt.include.compile.classpath в разделе <properties>:
<properties>
<kapt.include.compile.classpath>false</kapt.include.compile.classpath>
</properties>
Если параметру задано значение false, процессоры аннотаций, не включенные в раздел <annotationProcessorPaths> конфигурации kapt, исключаются из обработки kapt.
Если параметр includeCompileClasspath не задан и kapt обнаруживает в пути классов компиляции процессор аннотаций, который явно не указан в разделе <annotationProcessorPaths>, вы увидите следующее предупреждение об устаревании:
[WARNING] Annotation processors discovery from compile classpath is deprecated. Set 'kapt.include.compile.classpath=false' to disable discovery.
Подробнее о настройке kapt см. в нашей документации.
Power-assert: новая библиотека времени выполнения
В Kotlin 2.4.0 стало проще находить функции, поддерживающие Power-assert, и настраивать их с помощью новой библиотеки времени выполнения.
Ранее для использования Power-assert требовались сложные настройки сборки и соглашения об именовании параметров функций. Начиная с этого выпуска, функции, поддерживающие Power-assert, могут использовать новую библиотеку времени выполнения для прямой интеграции с преобразованиями плагина компилятора.
Это дает значительные преимущества как пользователям плагина, так и авторам библиотек:
Новая структура данных
CallExplanationпредоставляет подробную информацию о месте вызова. Благодаря этому можно динамически отображать диаграммы при сбоях утверждений и улучшить интеграцию с внешними инструментами.Новая аннотация
@PowerAssertпозволяет плагину компилятора сразу находить функции утверждений. Теперь вы можете добавить в свои библиотеки встроенную поддержку Power-assert.
Подробнее см. в нашей документации.
Компилятор Compose
В Kotlin 2.4.0 компилятор Compose обеспечивает более согласованную инкрементальную компиляцию и продолжает цикл вывода из употребления нескольких флагов функций.
Согласованная инкрементальная компиляция для внутренних объявлений
Начиная с Kotlin 2.4.0 компилятор Compose обеспечивает более согласованную инкрементальную компиляцию. Стабильность внутренних типов в разных файлах теперь определяется во время выполнения. Это позволяет Compose обновлять выведенные значения стабильности, даже если места использования класса не компилируются повторно.
В качестве побочного эффекта размер артефактов может увеличиться, если функция @Composable использует класс internal из другого файла в качестве параметра. Это происходит потому, что компилятор кодирует пути выполнения как для стабильных, так и для нестабильных случаев, поскольку стабильность необходимо определять во время выполнения. Минимизаторы, выполняющие оптимизацию всего приложения (например, R8), устраняют эти накладные расходы, связанные со стабильностью во время выполнения, поскольку могут определить ненужный путь выполнения и удалить его.
Это обновление не меняет итоговое значение стабильности, поэтому поведение функций @Composable остается прежним.
Вывод флагов функций из употребления
В Kotlin 2.4.0 продолжается цикл вывода из употребления экспериментальных флагов функций, которые перешли в стабильную версию и теперь включены по умолчанию:
Для
StrongSkipping,IntrinsicRememberи связанных свойств DSL повышен уровень доDeprecationLevel.ERROR. Они будут удалены в Kotlin 2.5.0.OptimizeNonSkippingGroupsиPausableCompositionтеперь объявлены устаревшими. Их планируется удалить в Kotlin 2.6.0.
Несовместимые изменения и устаревшие функции
В этом разделе перечислены важные несовместимые изменения и устаревшие функции. Полный обзор см. в нашем руководстве по совместимости.
Начиная с Kotlin 2.4.0 компилятор больше не поддерживает
-language-version=1.9. В результате компилятор K1 больше не поддерживается.В Kotlin 2.4.0 упрощен DSL для проверки бинарной совместимости в плагине Kotlin Gradle, а некоторые его части объявлены устаревшими. Описание актуального DSL см. в разделе Проверка бинарной совместимости в плагине Kotlin Gradle.
Удалена поддержка выполнения скриптов Kotlin с помощью плагина Maven
KotlinScriptMojo.
Обновления документации
В документацию экосистемы Kotlin внесены следующие изменения:
Liquid Glass в приложении Compose Multiplatform – Узнайте, как перенести приложение iOS с полностью управляемой Compose навигации на нативную навигацию SwiftUI со стилем Liquid Glass из iOS 26.
Добавление пакетов Swift в качестве зависимостей модулей KMP – Узнайте, как настроить зависимость SwiftPM в проекте KMP.
Перенос проекта Kotlin Multiplatform с CocoaPods на зависимости SwiftPM вручную или с помощью Junie – Узнайте, как использовать Junie и навыки Kotlin AI, чтобы упростить миграцию.
Настройка TeamCity для приложения KMP – Используйте TeamCity для сборки, тестирования и развертывания приложений KMP.
Рекомендуемые способы сериализации для Navigation 3 – Выберите оптимальный способ использования сериализации с Navigation 3 в приложении CMP.
Мультиплатформенный ViewModel – Узнайте, как настроить ViewModel и работать с ним в мультиплатформенном проекте.
Разработка серверной части на Kotlin – Ознакомьтесь с различными фреймворками для разработки серверной части.
Создание приложения для управления задачами с помощью Spring Boot и Claude – Узнайте, как Claude поможет создать приложение на Spring Boot с нуля.
Настройка проекта Maven – Настройте компиляцию Kotlin в существующем проекте Java Maven или в новом проекте Kotlin Maven.
Тестирование проектов Kotlin с помощью Maven – Узнайте, как создавать тесты с JUnit и использовать плагины Maven для запуска модульных и интеграционных тестов.
Использование процессоров аннотаций в проектах Kotlin – Выберите между kapt и KSP для обработки аннотаций в серверном проекте.
Навыки Kotlin AI – Используйте навыки агентов для выполнения задач, связанных с Kotlin.
Сервер языка Kotlin – Узнайте об официальной реализации JetBrains протокола Language Server Protocol (LSP) для Kotlin.
Числа – Изучите числовые типы Kotlin и способы работы с ними.
Начало работы с KSP – Узнайте, как добавить в проект процессор на основе KSP или создать собственный.
Переход с kapt на KSP – Перенесите процессоры аннотаций, чтобы максимально использовать возможности Kotlin.
Обзор Lincheck – Узнайте, как Lincheck работает «за кулисами» при тестировании параллельного кода на JVM.
Начало работы с Lincheck – Создайте проект и запустите тесты с помощью Lincheck.
Тестирование произвольного кода с помощью Lincheck – Узнайте, как тестировать параллельный код с помощью Lincheck.
Как тестировать структуры данных с помощью Lincheck – Узнайте подробнее о процессе тестирования структур данных в Lincheck.
Стратегии тестирования в Lincheck – Узнайте о стратегиях тестирования Lincheck: проверке модели и стресс-тестировании.
Настройка стратегии тестирования в Lincheck – Изучите различные параметры стратегий тестирования Lincheck.
Развертывание приложения Ktor с помощью Dokku – Узнайте о процессе развертывания с помощью Dokku.
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/whatsnew24.html