На днях вышел очередной релиз Kotlin 2.1.20, который принес массу интересных обновлений. Давайте разберемся, что нового появилось в этой версии. 1
1. Основные изменения#
🔧 K2-компилятор и KAPT
KAPT по умолчанию на K2: Новый плагин kapt по умолчанию – вроде бы мелочь, но для тех, кто возится с аннотациями и препроцессингом, это может быть существенно. Раньше приходилось возиться с кучей конфигураций, теперь обещают больше стабильности.
Откат на K1: Добавьте в
gradle.properties
:kapt.use.k2=false
⚡ Kotlin/Native: Производительность
- Инлайн-оптимизация (экспериментально):
Инлайн-оптимизации в Kotlin/Native – вещь, которую оценят только настоящие перфекционисты. Миллисекунды? Да. Принципиально? Абсолютно.
Эта оптимизация превосходит стандартный инлайнер LLVM и ускоряет выполнение программ.
Как включить:
-Xbinary=preCodegenInlineThreshold=40
- Значение 40 — оптимальный порог для баланса между оптимизацией и временем компиляции.
- Можно экспериментировать с другими значениями (чем выше, тем агрессивнее оптимизация).
Результаты: +9.5% к скорости выполнения (по тестам JetBrains).
🌐 WebAssembly
- Кастомные форматтеры по умолчанию в dev-сборках. Дефолтные кастомные форматтеры в Wasm – это уже интересно. Web-разработчики получают немного больше контроля без лишних плясок с бубном.
// build.gradle.kts
kotlin {
wasmJs {
// ...
compilerOptions {
freeCompilerArgs.add("-Xwasm-debugger-custom-formatters")
}
}
}
- DWARF-отладка (для Wasm VM):Что даёт: инспекция переменных, пошаговая отладка.
-Xwasm-generate-dwarf
2. Экспериментальные возможности#
🛠 Поддержка Lombok @SuperBuilder и улучшения @Builder
- Kotlin Lombok plugin теперь поддерживает аннотацию @SuperBuilder, упрощая создание билдеров для иерархий классов. Раньше при наследовании приходилось вручную описывать логику для суперклассов — теперь это делается автоматически.
Что изменилось:
- @SuperBuilder:
- Автоматически наследует поля родительского класса.
- Позволяет инициализировать поля суперкласса при создании объекта.
@SuperBuilder
public class Parent {
private String parentField;
1
}
@SuperBuilder
public class Child extends Parent {
private String childField;
}
// Использование в Kotlin:
val child = Child.builder()
.parentField("value")
.childField("anotherValue")
.build()
- @Builder на конструкторах:
- Теперь работает с конструкторами, предлагая гибкие варианты создания объектов.
public class User {
@Builder
public User(String name, int age) { ... }
}
📦 Новый DSL для Multiplatform
С Gradle 8.7 старый Application plugin несовместим с Kotlin Multiplatform. Появился новый экспериментальный DSL с блоком executable {}:
kotlin {
jvm {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
binaries {
executable {
mainClass.set("foo.MainKt")
}
// Можно настроить несколько точек входа
executable(KotlinCompilation.MAIN_COMPILATION_NAME, "another") {
mainClass.set("foo.MainAnotherKt")
}
}
}
}
Важно: Требуется @OptIn(ExperimentalKotlinGradlePluginApi::class)
📤 Кастомные публикации в Gradle
Добавление своих вариантов публикации для JVM и Multiplatform (экспериментально):
Возможность добавлять кастомные варианты публикации. Звучит скучно? Для кого-то – да. Для того, кто хочет максимально тонко настроить сборку – почти как панацея.
plugins {
kotlin("jvm") // или multiplatform
}
kotlin {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
publishing {
adhocSoftwareComponent {
// Конфигурация кастомных вариантов
}
}
}
⏱️ Трекинг времени в stdlib
Новые классы Clock
и Instant
(аналоги из kotlinx-datetime
):
@OptIn(ExperimentalTime::class)
fun main() {
val now = Clock.System.now()
val past = Instant.parse("2023-01-01T00:00:00Z")
println("Прошло времени: ${now - past}")
}
Конвертеры:
.toJavaInstant()
→java.time.Instant
.toJSDate()
→ JSDate
(с потерей точности).
3. Kotlin/Wasm: Миграция на Provider API#
Раньше:
the<NodeJsExtension>().version = "2.0.0"
Теперь:
the<NodeJsEnvSpec>().version.set("2.0.0")
Зачем: Ленивые вычисления и улучшенная интеграция с задачами Gradle.
🚨 Заменили устаревшее
Устарело | Замена |
---|---|
wasmJsRun | wasmJsBrowserDevelopmentRun |
wasmJsBrowserRun | wasmJsBrowserDevelopmentRun |
wasmJsNodeRun | wasmJsNodeDevelopmentRun |
wasmJsBrowserWebpack | wasmJsBrowserProductionWebpack или wasmJsBrowserDistribution |
jsRun | jsBrowserDevelopmentRun |
jsBrowserRun | jsBrowserDevelopmentRun |
jsNodeRun | jsNodeDevelopmentRun |
jsBrowserWebpack | jsBrowserProductionWebpack или jsBrowserDistribution |
4. Стандартная библиотека#
- Атомарные типы: Для конкурентных операций.
- UUID: Улучшенная генерация и сериализация.
- Трекинг времени: Точное измерение интервалов (см. раздел 2).
5. Compose: Отладка и оптимизации#
- Исходная информация включена по умолчанию для всех платформ.
- Поддержка default-аргументов в open-функциях:Важно: Требуется Kotlin 2.1.20+ для корректной работы.
open class MyComponent { @Composable open fun Content(text: String = "default") { ... } }
- Финальные функции могут быть restartable: Убрано ограничение для
final override
. - Удаление ComposableSingletons из публичного API: Устранение утечек в inline-функциях.
6. Gradle#
- Поддержка версий: 7.6.3 – 8.11 (с предупреждениями в новых версиях).
- Изолированные проекты (pre-Alpha):
- Включите через системное свойство.
- JS/Wasm пока не поддерживаются.
- Отключение для Multiplatform:
kotlin.kmp.isolated-projects.support=disable
- Кастомные публикации: Экспериментальный API (см. раздел 2).
7. Установка#
- IntelliJ IDEA 2023.3+ и Android Studio Iguana: Плагин встроен.
- Обновление: Пропишите в
build.gradle
:plugins { kotlin("jvm") version "2.1.20" }
8. Breaking Changes#
- Устарело:
withJava()
→ Java-сорс-сеты создаются автоматически.kotlin-android-extensions
→ Полная блокировка (ошибка конфигурации).
- Удалено: Свойство
kotlin.incremental.classpath.snapshot.enabled
.
Итоги#
Kotlin 2.1.20 фокусируется на производительности (Native, K2), упрощении конфигурации (Multiplatform DSL) и отладке (Wasm DWARF, Compose). Экспериментальные фичи вроде @SuperBuilder
и нового DSL дают заглянуть в будущее языка.
🔗 https://github.com/JetBrains/kotlin/releases/tag/v2.1.20
Внимание: Все экспериментальные фичи требуют явного @OptIn
!
P.S. Если заметили баги с K2 — не паникуйте, всегда можно откатиться на K1 через gradle.properties
.
Тестируйте и программируйте в удовольствие! 🚀