Skip to content

필사 모드: モダン Kotlin 2026 — Kotlin 2.1 / K2 コンパイラ / Compose Multiplatform / KMP 2.1 / Ktor 3 / Spring Boot Kotlin 深掘りガイド

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

プロローグ — 2026 年の Kotlin はもう「Android の言語」ではない

2017 年の Google I/O で Android 公式言語になった日から、Kotlin はしばらく「Android のための Java 代替」として生きてきた。サーバ陣営は Java 17、21 を使えばよかったし、マルチプラットフォームはアルファからベータへゆっくりと進んでいた。

2026 年 5 月の風景は当時とまったく違う。

- **Kotlin 2.1**(2024 年 11 月)が **K2 コンパイラをデフォルト**に昇格させた。IDE も K2 モードがデフォルトで、クリーンビルドは K1 比平均 1.8 倍速い。

- **Kotlin 2.2**(2025 年 3 月)が **context parameters** — 旧 context receivers の正式な後継 — を導入。戻り値の型を汚さずに、関数シグネチャに依存性を結びつけられる。

- **Compose Multiplatform 1.7**(2024 年 10 月)が **iOS を stable** と宣言。Android・iOS・デスクトップ・Web(Wasm)を 1 コードベースで描く。

- **KMP(Kotlin Multiplatform)2.1** は production-ready を超え、メルカリ・マクドナルドなどがコア SDK を KMP に書き換えている。

- **Ktor 3**(2024 年 10 月)が **WebAssembly ターゲット**を追加し、kotlinx-io ベースで書き直されてスループットが平均 90% 上昇。

- **Spring Boot 3.5** は Kotlin を一級言語扱い。coroutine サポートは成熟、Kotlin DSL ビルドが標準。

本稿は「Kotlin を見始めたばかり」から「2026 年の本番でどう動くか全部見たい」までを一気に整理する。言語・コンパイラ・UI・サーバ・ライブラリ陣営・国内外事例を漏らさず押さえる。

1 章 · 2026 年のモダン Kotlin — Kotlin 2.x 時代の座標

まず座標を取ろう。2026 年 5 月時点の Kotlin フルスタックは次のとおり。

+----------------------------------------+

| Kotlin 2.2.x |

| (K2 compiler default, JVM/JS/Wasm) |

+----------------------------------------+

|

+-------------------+--------------------+

| | |

v v v

[JVM バックエンド] [マルチプラットフォーム] [Native / Wasm]

Spring Boot 3.5 KMP 2.1 + CMP 1.7 Kotlin/Native

Ktor 3 iOS/Android/Desktop Kotlin/Wasm

gRPC-Kotlin Web (Wasm) (Ktor 3 server)

| | |

+-------------------+--------------------+

|

v

+-------------------------+

| kotlinx ライブラリ |

| coroutines / Flow |

| serialization / io |

| datetime / atomicfu |

+-------------------------+

|

v

+---------------+----------------+

| | |

v v v

[DI/FP/ORM] [静的解析/テスト] [ビルド]

Koin / Arrow Detekt / Konsist Gradle Kotlin DSL

Exposed Kotest / MockK Maven Kotlin plugin

要点整理:

- 言語自体は 2 年に 1 度 major(1.x → 2.x)、半年に 1 度 minor。

- マルチプラットフォームはもう「実験」ではない。iOS stable がゲームチェンジャー。

- サーバ陣営は Spring Boot と Ktor の両方が健在。

- ライブラリ陣営(Koin/Arrow/Exposed/Kotest/MockK)が分厚く、Kotlin らしい流儀でフルスタックを組める。

この座標の上で、各エリアを一つずつ深掘りする。

2 章 · Kotlin 2.1(2024.11)— K2 デフォルト + マルチドル文字列

Kotlin 2.0 が K2 コンパイラを stable に昇格した最初のリリースなら、2.1 はそれを **全員に強制**したリリース。JetBrains は同時に IntelliJ IDEA の K2 モードもデフォルトにし、K1 フォールバックは 2025 年末までしかサポートしない。

2.1 のヘッドライン機能:

1. **K2 コンパイラがデフォルト** — `-language-version 2.0` 以上はすべて K2。

2. **マルチドル(`$$`、`$$$`)文字列補間** — テンプレートや LaTeX を扱うときの `$` エスケープ地獄から解放。

3. **`when` 式の guard condition** — `when (x) { is Foo if x.bar > 10 -> ... }` で分岐に追加条件をインラインで書ける。

4. **`.kotlin` キャッシュディレクトリ** — Gradle の `.gradle` のように、ビルド成果物をプロジェクト直下に集約。

5. **non-local `break` / `continue`** — inline ラムダ内からも外側のループを抜けられる(preview)。

マルチドル文字列は本当に楽になる。

// Kotlin 2.1: $$"..."$$ 内では単一の $ はリテラル、$$ で補間開始

val template = $$"""

Hello, $$name!

Your balance is $1000 (USD).

JSON: {"value": "$$value"}

"""

従来は毎回 `"\$1000"` のように `$` をエスケープするか、raw string にさらに別の文字列を継ぎ足す必要があった。これが一行で終わる。

`when` guard も頻出。

sealed interface Order

data class Pending(val amount: Int) : Order

data class Paid(val amount: Int, val txId: String) : Order

fun handle(order: Order) = when (order) {

is Pending if order.amount > 10_000 -> "high-value pending"

is Pending -> "pending"

is Paid -> "paid: ${order.txId}"

}

K1 では `is Pending` 分岐の中で `if` をネストする必要があり、その瞬間に exhaustive チェックが効かなくなった。今や一行で終わり、網羅性も維持される。

3 章 · Kotlin 2.2(2025.3)— context parameters

Kotlin 2.2 のヘッドラインは **context parameters** — 1.7 からベータで動いていた「context receivers」の正式後継。

何を解決するのか

関数に **暗黙的に** 依存性を注入したいことがある。例えば:

// 従来: 毎回 logger を明示的に受け取る

fun calculate(x: Int, y: Int, logger: Logger): Int {

logger.info("calc $x + $y")

return x + y

}

// あるいはクラスで包む

class Calculator(private val logger: Logger) {

fun calculate(x: Int, y: Int): Int { ... }

}

context parameters は **シグネチャに依存性を宣言しつつ、呼び出し側は明示的に渡さなくてよい** 中間路線。

// Kotlin 2.2 context parameters

context(logger: Logger)

fun calculate(x: Int, y: Int): Int {

logger.info("calc $x + $y")

return x + y

}

// 呼び出し側: スコープに Logger を持ち込めば自動注入

fun main() {

with(MyLogger()) {

val result = calculate(1, 2) // logger 明示なし

}

}

context receivers と何が違うか

旧 1.x の `context(Logger)` は **名前が無かった**。同じ型のコンテキストが二つ入ると衝突。2.2 の `context(logger: Logger)` は **名前付き**。Arrow の effect ライブラリ、Compose の CompositionLocal、structured logging が軒並みこれを基盤に書き直されている。

実例: Arrow の raise

context(raise: Raise<String>)

fun parsePositive(s: String): Int {

val n = s.toIntOrNull() ?: raise.raise("not a number: $s")

if (n <= 0) raise.raise("must be positive: $n")

return n

}

// 呼び出し側

fun main() {

val result = either {

val n = parsePositive("42")

n * 2

}

// result: Either.Right(84)

}

`Either<E, A>` のような結果型を露出させずにエラーチャネルを合成できる。Scala の ZIO や Haskell の monad transformer 流の effect system を Kotlin らしく落とし込んだ解。

4 章 · K2 コンパイラ — 何が速くなり、何が変わるのか

K2 はコンパイラのフロントエンドを **全面書き直し** した成果物。K1 は 2010 年代初頭の設計で、型推論・smart cast・generic inference のコードが複数のパスに散らばっていた。K2 は **FIR(Frontend IR)** という単一 IR に統一した。

体感効果:

| 指標 | K1 | K2 | 備考 |

|---|---|---|---|

| クリーンビルド | 1.0x | 1.6 〜 1.9x 高速 | 大規模プロジェクトほど差が大きい |

| インクリメンタルビルド | 1.0x | 2.0 〜 2.4x 高速 | キャッシュ / invalidation 改善 |

| IDE highlight | 1.0x | 1.5x 高速 | smart cast / 推論キャッシュ |

| ピークメモリ | 1.0x | 約 0.7x | FIR 統合で重複削減 |

数値は JetBrains 公式ベンチマーク + メルカリ・Square のマイグレーション報告の平均。

Smart cast がさらに賢くなった

K1 は複雑な分岐で一貫した型の絞り込みが苦手だった。

fun process(value: Any?) {

if (value is String || value is Int) {

// K1: value は依然 Any?

// K2: value は String | Int(intersection)

println(value.hashCode()) // K2 なら問題なく呼べる

}

}

K2 は **`val` の遅延初期化** パターンも認識する。

class Holder {

val data: List<Int>

init {

val tmp = mutableListOf<Int>()

tmp.add(1); tmp.add(2)

data = tmp.toList() // K2: OK

}

}

コンパイラプラグイン API の安定化

Compose コンパイラプラグイン、kotlinx-serialization、Arrow の raise プラグインがすべて K2 FIR ベースで書き直された。結果としてビルド時間が短縮、IDE インデックスも安定。

マイグレーションチェックリスト

- `kotlin.languageVersion = "2.1"` に上げる。

- `kotlin.compiler.execution.strategy = in-process`(Gradle daemon)。

- Compose プロジェクトは `compose-compiler-gradle-plugin`(2024 年から JetBrains が直接配布)を使う。

- `-Xuse-fir-lt` のような旧フラグを削除。

5 章 · Compose Multiplatform — iOS stable!

2024 年 10 月の Compose Multiplatform 1.7 は本当に大きな節目だった。**iOS ターゲットが stable** に昇格。それまで Compose-Android は本番品質だったが iOS はベータ。1.7 以降は本番 OK。

1.7 ヘッドライン(2024.10)+ 1.7+ の積み増し

- **iOS stable** — UIViewController 統合、テキスト入力、アクセシビリティ、ダークモードすべて stable。

- **Resource API 1.0** — drawable / string / font を `Res.drawable.icon` のような型安全プロキシで参照。

- **adaptive layouts** — `WindowSizeClass` API。スマホ / タブレット / フォルダブルの分岐。

- **Skia 0.8 → 0.10** — テキスト描画品質、GPU メモリ改善。

- **ホットリロード(desktop)** — Java 21 の enhanced class redefinition を活用。デザインループが本当に速い。

1 画面、4 プラットフォーム

// commonMain/HelloApp.kt

@Composable

fun HelloApp(name: String) {

MaterialTheme {

Column(modifier = Modifier.padding(16.dp)) {

Text("Hello, $name!", style = MaterialTheme.typography.headlineSmall)

Spacer(Modifier.height(8.dp))

Button(onClick = { /* ... */ }) {

Text("Tap me")

}

}

}

}

このまま Android、iOS、macOS / Windows / Linux デスクトップ、そして(実験的に)Web Wasm で動く。プラットフォーム固有部分だけ `expect` / `actual` に切り出す。

// commonMain

expect fun platformName(): String

// androidMain

actual fun platformName(): String = "Android ${Build.VERSION.RELEASE}"

// iosMain

actual fun platformName(): String =

UIDevice.currentDevice.systemName + " " + UIDevice.currentDevice.systemVersion

Compose vs SwiftUI 比較(2026)

| 項目 | Compose Multiplatform 1.7+ | SwiftUI |

|---|---|---|

| プラットフォーム | Android / iOS / Desktop / Web | Apple のみ |

| 言語 | Kotlin | Swift |

| コード共有 | 100%(UI まで) | 0%(他プラットフォーム) |

| iOS パフォーマンス | 95%(スクロール / アニメーション一部 gap 残) | 100% native |

| ネイティブウィジェット | `UIViewControllerRepresentable` 風の interop | 自然 |

| ビルド時間 | KMP のビルドオーバーヘッドあり | Xcode 標準 |

選び方:

- iOS のみ → SwiftUI。

- Android + iOS、デザイン一貫性が重要 → CMP。

- 「Apple の新 API をその日から使う」 → SwiftUI。

6 章 · KMP 2.1 — production-ready

Compose Multiplatform が UI なら、**KMP(Kotlin Multiplatform)** は **ロジック共有**。ビジネスロジック、ネットワーキング、ディスクキャッシュ、ドメインモデルを Kotlin で 1 度書いて、Android・iOS・サーバ・Web で使い回す。

KMP モジュール構成

shared/

build.gradle.kts

src/

commonMain/kotlin/ <- 全プラットフォーム共通コード

androidMain/kotlin/ <- Android 専用

iosMain/kotlin/ <- iOS 専用(Kotlin/Native)

jvmMain/kotlin/ <- JVM サーバ用

wasmJsMain/kotlin/ <- Wasm Web 用

commonTest/kotlin/ <- 共通テスト

コアライブラリ

- **kotlinx.coroutines** — どのプラットフォームでも同じ API。

- **kotlinx.serialization** — JSON / Protobuf / CBOR。multiplatform 標準。

- **Ktor Client** — multiplatform HTTP / WebSocket。

- **SQLDelight 2** — 型安全 SQL ドライバ。iOS / Android / JVM / Wasm 対応。

- **Multiplatform Settings** — UserDefaults / SharedPreferences / ファイルを抽象化。

- **Decompose / Voyager** — multiplatform ナビゲーション。

- **Koin** — DI、multiplatform。

iOS 統合 — KMP 成果物を Xcode へ

// shared/build.gradle.kts

kotlin {

iosX64()

iosArm64()

iosSimulatorArm64()

cocoapods {

version = "1.0"

summary = "Shared module for MyApp"

homepage = "https://example.com"

ios.deploymentTarget = "15.0"

framework {

baseName = "Shared"

isStatic = false

}

}

}

./gradlew :shared:podPublishXcFramework

成果物を Xcode プロジェクトの Podfile に追加

Swift 側はそのまま import。

let repo = UserRepository()

Task {

let users = try await repo.fetchUsers()

print(users)

}

Kotlin の `suspend fun` は Swift の `async throws` に自動マッピングされる(2.1 と Kotlin/Native の swift-export 改善のおかげ)。

メルカリ、マクドナルドなどの事例

- **メルカリ** — 検索 / 決済のコアロジックを KMP に移行。Android / iOS のバグが 1 か所で直る。

- **マクドナルド** — Global Mobile App を KMP ベースで再構築。

- 国内事例(メルカリ・ZOZO・CyberAgent)は 13 章で詳しく。

7 章 · Ktor 3(2024.10)— WebAssembly ターゲット

Ktor 3 は 2024 年 10 月リリース。「v2 のマイナーアップ」ではなく **ほぼ書き直し** のメジャー。

ヘッドライン

1. **kotlinx-io ベースに書き直し** — okio / java.nio 依存を撤廃。スループット平均 +90%。

2. **WebAssembly ターゲット** — Kotlin/Wasm で Ktor サーバが組める。エッジコンピュートのシナリオ。

3. **CIO エンジン HTTP/2 stable** — 外部依存なしで HTTP/2 サーバを立てられる。

4. **Server-Sent Events プラグイン** — `install(SSE)`。

5. **WebSocket extensions** — Compression、ping / pong を再設計。

最小 Ktor 3 サーバ

// build.gradle.kts

plugins {

kotlin("jvm") version "2.1.0"

application

}

dependencies {

implementation("io.ktor:ktor-server-core:3.0.0")

implementation("io.ktor:ktor-server-cio:3.0.0")

implementation("io.ktor:ktor-server-content-negotiation:3.0.0")

implementation("io.ktor:ktor-serialization-kotlinx-json:3.0.0")

}

// src/main/kotlin/Application.kt

@Serializable

data class User(val id: Long, val name: String)

fun main() {

embeddedServer(CIO, port = 8080) {

install(ContentNegotiation) { json() }

routing {

get("/users") {

call.respond(listOf(User(1, "Alice"), User(2, "Bob")))

}

}

}.start(wait = true)

}

`./gradlew run` で 8080 から JSON が返る。coroutine ベースなので thread-per-request ではなく、1 スレッドが数千コネクションを捌く。

Spring Boot vs Ktor — どこで何を使うか

| 項目 | Ktor 3 | Spring Boot 3.5 + Kotlin |

|---|---|---|

| 哲学 | minimal、opt-in plugins | 「convention over config」 |

| 並行モデル | coroutine native | WebFlux(reactive)or virtual threads |

| エコシステム | 軽量 | 巨大、なんでもある |

| コールドスタート | 速い | GraalVM native image なら速い |

| 学習コスト | 短い | 長いが資料豊富 |

| 向き | マイクロサービス、エッジ、MVP | 大型モノリス、エンタープライズ |

8 章 · Spring Boot + Kotlin — JVM サーバ

JVM サーバで Kotlin を使うと言われたとき、企業の 70% は依然 Spring Boot。そして Spring チームはそのトラフィックを無視しなかった。Spring Framework 6、Boot 3 系列は Kotlin サポートを「一級」に格上げした。

モダン Spring Boot + Kotlin スタック(2026)

- **Spring Boot 3.5**(Java 21 baseline、Kotlin 2.1+)

- **Spring WebFlux + coroutines** — `suspend` 関数をコントローラで直接受ける。

- **R2DBC + Kotlin Coroutines** — async DB。

- **Spring Security 6** — Kotlin DSL。

- **Spring AOT + GraalVM native image** — コールドスタート 100 ms 未満。

Coroutine コントローラ

@RestController

class UserController(private val repo: UserRepository) {

@GetMapping("/users/{id}")

suspend fun getUser(@PathVariable id: Long): UserDto =

repo.findById(id)?.toDto() ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)

@GetMapping("/users", produces = [MediaType.APPLICATION_NDJSON_VALUE])

fun streamUsers(): Flow<UserDto> =

repo.findAll().map { it.toDto() }

}

`suspend fun` をそのまま受け取る。WebFlux の `Mono` / `Flux` を変換する必要はない。`Flow<UserDto>` は NDJSON ストリーミングレスポンスへ自動変換。

Coroutine リポジトリ(R2DBC)

interface UserRepository : CoroutineCrudRepository<UserEntity, Long> {

suspend fun findByEmail(email: String): UserEntity?

@Query("SELECT * FROM users WHERE created_at > :since")

fun findRecentUsers(since: Instant): Flow<UserEntity>

}

Kotlin DSL コンフィグ

@Configuration

class AppConfig {

@Bean

fun routes(handler: UserHandler) = coRouter {

accept(MediaType.APPLICATION_JSON).nest {

GET("/users", handler::list)

POST("/users", handler::create)

}

}

@Bean

fun securityFilter(http: ServerHttpSecurity): SecurityWebFilterChain =

http {

authorizeExchange {

authorize("/public/**", permitAll)

authorize(anyExchange, authenticated)

}

oauth2ResourceServer { jwt {} }

}

}

`http { ... }` が Kotlin DSL。XML / Java config のボイラープレートが消える。

9 章 · kotlinx.coroutines + Flow — async モデル

Kotlin の async モデルは 2 軸。**coroutines**(一度完結する非同期処理)と **Flow**(時間軸を流れる値のストリーム)。

Coroutines 基本

suspend fun fetchUser(id: Long): User { /* HTTP 呼び出し */ }

suspend fun fetchOrders(userId: Long): List<Order> { /* HTTP 呼び出し */ }

suspend fun loadProfile(id: Long): Profile = coroutineScope {

val userDeferred = async { fetchUser(id) }

val ordersDeferred = async { fetchOrders(id) }

Profile(userDeferred.await(), ordersDeferred.await())

}

`coroutineScope` 内で 2 つのタスクが並列に走り、どちらかが失敗すればもう一方も cancel — **structured concurrency**。

Flow — cold stream

fun userUpdates(userId: Long): Flow<UserEvent> = flow {

while (currentCoroutineContext().isActive) {

val event = pollEvent(userId)

if (event != null) emit(event)

delay(1000)

}

}

// 消費側

suspend fun watchUser() {

userUpdates(42L)

.filter { it.type == EventType.UPDATED }

.map { it.toDto() }

.take(10)

.collect { println(it) }

}

Flow は **cold** — `.collect` を呼ぶたびに最初から再実行。hot stream が要るなら `SharedFlow` / `StateFlow`。

StateFlow — UI state holder

class UserViewModel(private val repo: UserRepository) {

private val _state = MutableStateFlow<UserState>(UserState.Loading)

val state: StateFlow<UserState> = _state.asStateFlow()

fun load(id: Long) {

viewModelScope.launch {

_state.value = UserState.Loading

_state.value = runCatching { repo.findById(id) }

.fold(

onSuccess = { UserState.Loaded(it) },

onFailure = { UserState.Error(it.message ?: "") }

)

}

}

}

Compose では `val state by viewModel.state.collectAsState()` で受けてそのまま描画。

Coroutine デバッガ

IntelliJ の `Debug` メニュー → `Coroutines Dump`。どの coroutine がどこで suspended かをツリーで表示。Java スレッドダンプとは比較にならない便利さ。

10 章 · Detekt / Konsist — 静的解析 + アーキテクチャテスト

Kotlin のコード品質を自動で守る 2 つの道具。

Detekt — コードスメル静的解析

// build.gradle.kts

plugins {

id("io.gitlab.arturbosch.detekt") version "1.23.7"

}

detekt {

toolVersion = "1.23.7"

config.setFrom("$rootDir/detekt.yml")

buildUponDefaultConfig = true

}

`detekt.yml` 抜粋:

complexity:

CyclomaticComplexMethod:

threshold: 15

LongMethod:

threshold: 60

naming:

FunctionNaming:

functionPattern: '[a-z][a-zA-Z0-9]*'

style:

MagicNumber:

ignoreNumbers: ['-1', '0', '1', '2']

CI 連携:

./gradlew detekt

結果: build/reports/detekt/detekt.html

K2 互換は 1.23 から stable、2025 年半ばの 1.24 からは K2 専用解析ルール(smart-cast hint、sealed exhaustive など)が追加された。

Konsist — アーキテクチャテスト

ArchUnit の Kotlin 版。**レイヤ依存、命名規則、アノテーション利用** をユニットテストとして検証する。

// src/test/kotlin/ArchitectureTest.kt

class ArchitectureTest {

@Test

fun `repositories should not depend on controllers`() {

Konsist.scopeFromProject()

.classes()

.withNameEndingWith("Repository")

.assertTrue { repo ->

repo.containingFile.imports

.none { it.name.contains("controller") }

}

}

@Test

fun `all use cases end with UseCase`() {

Konsist.scopeFromPackage("..usecase..")

.classes()

.assertTrue { it.name.endsWith("UseCase") }

}

}

`./gradlew test` で自動実行。新人が「controller から repository を直接呼び出す」PR を出すと CI が赤くなる。

Detekt が「ファイル内のコード品質」、Konsist が「プロジェクト全体の構造」。両者は補完関係。

11 章 · Koin / Arrow / Exposed / Kotest / MockK — ライブラリ陣営

Java の Spring / Hibernate / Mockito に対応する「Kotlin native」ライブラリたち。

Koin — DSL ベースの DI

val appModule = module {

single<UserRepository> { UserRepositoryImpl(get()) }

single<HttpClient> {

HttpClient(CIO) {

install(ContentNegotiation) { json() }

}

}

viewModel { UserViewModel(get()) }

}

fun main() {

startKoin {

modules(appModule)

}

// ...

}

リフレクションなし。Dagger のような compile-time generation もなし。KMP 互換。Compose Multiplatform でもそのまま使われる。

Arrow — Kotlin の FP 標準

sealed interface UserError {

object NotFound : UserError

data class Invalid(val reason: String) : UserError

}

fun parseAge(s: String): Either<UserError, Int> = either {

val n = s.toIntOrNull() ?: raise(UserError.Invalid("not a number: $s"))

if (n < 0 || n > 150) raise(UserError.Invalid("age out of range: $n"))

n

}

fun loadUser(id: Long): Either<UserError, User> = either {

val user = repo.find(id) ?: raise(UserError.NotFound)

user

}

fun process(id: Long, ageStr: String): Either<UserError, Result> = either {

val user = loadUser(id).bind()

val age = parseAge(ageStr).bind()

Result(user, age)

}

**`Either<L, R>`** と **`raise` DSL** の組み合わせで throw なしにエラーを合成。2.2 の context parameters と組み合わせると effect system が完成する。

Exposed — 型安全 SQL DSL

object Users : LongIdTable("users") {

val name = varchar("name", 100)

val email = varchar("email", 200).uniqueIndex()

val createdAt = timestamp("created_at").defaultExpression(CurrentTimestamp)

}

transaction {

val newId = Users.insertAndGetId {

it[name] = "Alice"

it[email] = "alice@example.com"

}

val users = Users

.selectAll()

.where { Users.name like "A%" }

.orderBy(Users.createdAt to SortOrder.DESC)

.limit(10)

.map { it[Users.name] to it[Users.email] }

}

JPA より軽量で、Hibernate の lazy-loading の罠もない。R2DBC アダプタで coroutine 環境でも動く(1.0 から stable)。

Kotest — BDD スタイルのテスト

class UserSpec : StringSpec({

"user with valid email should be created" {

val u = User("alice@example.com")

u.isValid shouldBe true

}

"negative age should throw" {

shouldThrow<IllegalArgumentException> {

User("a@b", age = -1)

}

}

})

class PropertySpec : StringSpec({

"reverse twice is identity" {

checkAll<List<Int>> { list ->

list.reversed().reversed() shouldBe list

}

}

})

JUnit 互換、式ベースの assertion、property-based testing(QuickCheck 流)を内蔵。multiplatform。

MockK — pure Kotlin mocking

class UserServiceTest : StringSpec({

val repo = mockk<UserRepository>()

val service = UserService(repo)

"should return user from repo" {

coEvery { repo.findById(1L) } returns User(1, "Alice")

val u = service.getUser(1L)

u.name shouldBe "Alice"

coVerify(exactly = 1) { repo.findById(1L) }

}

})

Mockito が扱えない `object`、`companion object`、トップレベル関数、suspend 関数を全部 mock できる。

12 章 · Gradle Kotlin DSL — ビルド標準

2026 年時点で **新規 Kotlin プロジェクトの 99% は Gradle Kotlin DSL**(`build.gradle.kts`)。Groovy DSL はレガシー。

最小 `build.gradle.kts`

plugins {

kotlin("jvm") version "2.1.0"

kotlin("plugin.serialization") version "2.1.0"

application

}

group = "com.example"

version = "0.1.0"

repositories {

mavenCentral()

}

dependencies {

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")

implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")

testImplementation(kotlin("test"))

testImplementation("io.kotest:kotest-runner-junit5:5.9.1")

}

application {

mainClass.set("com.example.AppKt")

}

kotlin {

jvmToolchain(21)

}

tasks.test {

useJUnitPlatform()

}

Multi-module + version catalog

`gradle/libs.versions.toml`:

[versions]

kotlin = "2.1.0"

coroutines = "1.9.0"

ktor = "3.0.0"

[libraries]

kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }

ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }

ktor-server-cio = { module = "io.ktor:ktor-server-cio", version.ref = "ktor" }

[plugins]

kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

ktor = { id = "io.ktor.plugin", version.ref = "ktor" }

各モジュールの `build.gradle.kts`:

plugins {

alias(libs.plugins.kotlin.jvm)

alias(libs.plugins.ktor)

}

dependencies {

implementation(libs.ktor.server.core)

implementation(libs.ktor.server.cio)

implementation(libs.kotlinx.coroutines)

}

バージョンを 1 か所で管理。30 モジュール超のプロジェクトで真価を発揮する。

configuration cache + build cache

gradle.properties

org.gradle.configuration-cache=true

org.gradle.caching=true

org.gradle.parallel=true

kotlin.incremental=true

kotlin.code.style=official

設定キャッシュは 8.x から stable。ビルド時間は明確に 2〜5 倍速くなる(特にインクリメンタル)。

Maven は死んだか?

否。**Spring Boot エンタープライズ + 既存 Maven 資産の大きい組織** は依然 Maven Kotlin plugin を使う。

機能的には同等。Gradle より遅いが安定。

13 章 · 韓国 / 日本 — カカオ、トス、メルカリ、ZOZO、CyberAgent

韓国

**カカオ(Android 全社 Kotlin)**

- KakaoTalk Android コードベースの 95% 以上が Kotlin。新規 Java コード禁止。

- 100 以上のモジュールで multi-module、Gradle Kotlin DSL + version catalog。

- 社内で Detekt + カカオ独自ルール(`KakaoCodeStyle`)を配布。

- Compose 移行進行中(2026 年時点、新規画面は 100% Compose)。

**トス(Toss)— Server-side Kotlin の先駆者**

- バックエンドの新規マイクロサービスは 100% Kotlin + Spring Boot。200 以上のサービスが Kotlin。

- Coroutine + WebFlux + R2DBC + Arrow の組み合わせが標準。

- 社内 Kotlin DSL ライブラリ(`tossopen-kotlin-commons`)多数。

- トス技術ブログに「Spring の Kotlin マイグレーション」「なぜ Java ではなく Kotlin か」シリーズが多数。

**LINE(NAVER)— Kotlin Multiplatform ケース**

- LINE メッセンジャーのクライアント SDK の一部を KMP で共有。2026 年時点で本番一部導入。

日本

**メルカリ — KMP の先駆者**

- 検索 / 決済のコア SDK を KMP で再構築。Android / iOS のバグ修正が 1 か所で済む。

- 2025 年発表:「共有ビジネスロジックの 60% を KMP に移行した」。

- Compose Multiplatform 1.7+ を評価中。

**ZOZOTOWN(ZOZO)**

- Android はフル Kotlin。サーバ一部 Kotlin(Spring Boot + Coroutines)。

- 社内 "Kotlin Guild" — 隔週勉強会、ライブラリ共有。

**CyberAgent(AbemaTV、FRIDAY ほか)**

- Android 新規プロジェクトは 100% Kotlin。

- AbemaTV Android — Compose + Coroutines + Koin + Coil。

- 一部マイクロサービスで Ktor 3 を導入(ストリーミングメタデータサービス)。

**DeNA / GREE / 楽天**

- 同様パターン:Android フル Kotlin、サーバ部分的に Kotlin。

共通パターン

韓国・日本の大企業すべてに共通:

1. Android は **100% Kotlin** が既に完了。

2. サーバは **新規マイクロサービスから** Kotlin へ移行。

3. KMP は **コア SDK 中心の選択的導入**(アプリ全体 KMP はまだ稀)。

4. 社内コーディングガイドは **Detekt ベース + 自社ルール**。

5. 採用市場:Kotlin 経験者 = Android + Server 両面に魅力。

14 章 · 誰が Kotlin を選ぶべきか — Android / KMP / JVM サーバ / FP

最後に意思決定マトリクス。「Kotlin が正解か」シナリオ別の答え。

「Android アプリを書く」

→ **Kotlin がデフォルト。他の選択肢が事実上ない。**

- Android Studio が Kotlin 優先。

- Jetpack Compose の正式言語。

- Google の新ライブラリ / ドキュメントはすべて Kotlin 優先。

「iOS + Android 両方、1 チームで」

→ **KMP + Compose Multiplatform を検討。**

条件:

- iOS の新 API をその日から使う必要がない(SwiftUI / AppKit の新機能を 1〜2 か月遅れで OK)。

- ビジネスロジックが両プラットフォームで同一。

- iOS デザイナーが「これは正確に iOS-native でなければ」と固執しない。

3 つすべて OK なら KMP。1 つでも NG ならネイティブ 2 本立て。

「Spring Boot 環境で JVM サーバを書く」

→ **Kotlin が Java よりほぼ全方面で優位。**

- Null safety = NPE をコンパイル時に潰す。

- Coroutines = `CompletableFuture` より圧倒的に読みやすい。

- Data class = Lombok 不要。

- Spring 6 / Boot 3.5 = Kotlin 一級サポート。

例外:チームの 80% が Java しか知らない → 段階導入(テストコードから、新規マイクロサービスから)。

「マイクロサービスを軽量に、GraalVM native image で」

→ **Ktor 3 + Kotlin/Native、または Ktor 3 + GraalVM。**

- コールドスタート 100 ms 未満。

- メモリ 50 MB 未満。

- ラムダ / エッジ関数にぴったり。

「関数型プログラミングを本気で」

→ **Kotlin + Arrow。ただし学習曲線は急。**

- Either / IO / context parameters / raise DSL の組み合わせ。

- Scala や Haskell ほど深くはないが、JVM 陣営における「産業向き FP」の sweet spot。

「データエンジニアリング、Spark / Flink」

→ **Scala が依然優位。Kotlin は補助。**

- Spark Kotlin API は存在するが Scala ほど成熟していない。

- ただし KEDB(Kotlin Embedded DB)など新興ツールは Kotlin 優先。

「Android でも JVM でもない」

→ Kotlin は別に来なくてよい。JS / Wasm ターゲットはあるが、その領域では TypeScript / Rust がデフォルト。

参考 / References

Kotlin 言語・コンパイラ公式

- Kotlin Blog — https://blog.jetbrains.com/kotlin/

- Kotlin 2.1.0 released — https://blog.jetbrains.com/kotlin/2024/11/kotlin-2-1-0-released/

- Kotlin 2.2.0 released — https://blog.jetbrains.com/kotlin/2025/03/kotlin-2-2-released/

- Kotlin 公式ドキュメント — https://kotlinlang.org/docs/home.html

- K2 compiler announcement — https://blog.jetbrains.com/kotlin/2024/04/k2-compiler-performance-benchmarks-and-how-to-measure-them-on-your-projects/

- KEEP (Kotlin Evolution and Enhancement Process) — https://github.com/Kotlin/KEEP

- Context parameters KEEP — https://github.com/Kotlin/KEEP/blob/master/proposals/context-parameters.md

Compose Multiplatform / KMP

- Compose Multiplatform — https://www.jetbrains.com/lp/compose-multiplatform/

- Compose Multiplatform 1.7 release (iOS stable) — https://blog.jetbrains.com/kotlin/2024/10/compose-multiplatform-1-7-0-release/

- Kotlin Multiplatform 公式 — https://kotlinlang.org/docs/multiplatform.html

- KMP wizard — https://kmp.jetbrains.com/

Ktor / Spring

- Ktor 3 release — https://blog.jetbrains.com/kotlin/2024/10/ktor-3-released/

- Ktor 公式ドキュメント — https://ktor.io/docs/welcome.html

- Spring Boot Kotlin support — https://docs.spring.io/spring-framework/reference/languages/kotlin.html

- Spring Boot + Coroutines — https://docs.spring.io/spring-framework/reference/languages/kotlin/coroutines.html

kotlinx ライブラリ

- kotlinx.coroutines — https://github.com/Kotlin/kotlinx.coroutines

- kotlinx.serialization — https://github.com/Kotlin/kotlinx.serialization

- kotlinx-io — https://github.com/Kotlin/kotlinx-io

静的解析・テスト・DI・FP・ORM

- Detekt — https://detekt.dev/

- Konsist — https://docs.konsist.lemonappdev.com/

- Koin — https://insert-koin.io/

- Arrow — https://arrow-kt.io/

- Exposed — https://www.jetbrains.com/help/exposed/home.html

- Kotest — https://kotest.io/

- MockK — https://mockk.io/

Gradle / ビルド

- Gradle Kotlin DSL primer — https://docs.gradle.org/current/userguide/kotlin_dsl.html

- Version catalogs — https://docs.gradle.org/current/userguide/platforms.html

企業ケース

- Toss 技術ブログ — https://toss.tech/

- カカオ技術ブログ — https://tech.kakao.com/

- Mercari Engineering Blog — https://engineering.mercari.com/blog/

- ZOZO Technologies — https://techblog.zozo.com/

- CyberAgent Developers Blog — https://developers.cyberagent.co.jp/blog/

- LINE Engineering — https://engineering.linecorp.com/

締めくくり。Kotlin 2.x はもはや「Java より少し良い Android 用言語」ではない。**コンパイラ(K2)、UI(Compose Multiplatform)、マルチプラットフォーム(KMP)、サーバ(Spring / Ktor)、ライブラリ陣営(Koin / Arrow / Exposed / Kotest)** が揃って stable に並んだ、2026 年 JVM 陣営のデフォルト言語である。本稿がその座標を取る助けになれば。

현재 단락 (1/627)

2017 年の Google I/O で Android 公式言語になった日から、Kotlin はしばらく「Android のための Java 代替」として生きてきた。サーバ陣営は Java 17、2...

작성 글자: 0원문 글자: 22,463작성 단락: 0/627