Kotlin

技术栈
后端框架
jvmandroidjetbrainsmoderncoroutines

概览

Kotlin 技术栈概览

Kotlin 是 JetBrains 于 2011 年发布的现代 JVM 语言,2017 年被 Google 宣布为 Android 官方首选语言。它完全兼容 Java,并以简洁语法、空安全、协程并发三大杀器著称,目前在服务端(Spring Boot)、Android、跨平台(KMP)三大方向高速增长。

解决什么问题

  • Java 冗长样板代码 → data class、扩展函数、类型推断精简 40%+
  • NullPointerException → 编译期空安全类型系统
  • 异步回调地狱 → 协程(Coroutine)用同步写法写异步
  • Java 互操作 → 100% 兼容,可混编渐进迁移
  • 多平台开发 → Kotlin Multiplatform(KMP)共享业务逻辑

关键特性

  • 空安全(Null Safety)String 不能为 null,String? 可以为 null
  • 数据类(data class):一行代码生成 equals/hashCode/toString/copy
  • 扩展函数:不修改源码给已有类添加方法
  • 协程(Coroutines):结构化并发,suspend 函数
  • 密封类(sealed class):受限类层次,配合 when 穷举
  • 委托(Delegation)by 关键字,属性委托(lazy/observable)
  • 作用域函数let/run/with/apply/also

安装

环境准备

  • JDK:8 / 11 / 17 / 21
  • IDE:IntelliJ IDEA(Kotlin 同厂 JetBrains 出品,支持最佳)
  • 构建工具:Gradle(官方推荐)或 Maven

安装命令

命令行编译器(可选)

# macOS
brew install kotlin

# Linux (SDKMAN)
sdk install kotlin

# 验证
kotlinc -version

Gradle 项目(最常用)

gradle init --type kotlin-application

build.gradle.kts 最小配置:

plugins {
    kotlin("jvm") version "1.9.22"
    application
}

group = "com.example"
version = "1.0.0"

repositories { mavenCentral() }

dependencies {
    testImplementation(kotlin("test"))
}

application { mainClass.set("com.example.MainKt") }

Spring Boot + Kotlin

通过 Spring Initializr 选择 Kotlin + Gradle-Kotlin DSL:

curl https://start.spring.io/starter.zip \
  -d language=kotlin \
  -d dependencies=web \
  -o demo.zip

常见问题

Q1: Unresolved reference: ...

检查依赖是否添加,以及 import 语句。Kotlin 的顶级函数编译后类名为 文件名Kt

Q2: Kotlin 版本与插件版本不一致

gradle.properties 中统一管理:

kotlin.code.style=official
kotlin.version=1.9.22

Q3: IDEA 中 Kotlin 插件未启用

Preferences → Plugins → 搜索 Kotlin → 确认已安装并启用。

示例

Kotlin 例程:协程、数据类与作用域函数

目标

对比 Java 冗长代码,展示 Kotlin 四大杀器:data class、扩展函数、协程、作用域函数。

完整代码

import kotlinx.coroutines.*
import java.time.LocalDateTime

// ── 1. data class:一行替代 Java 的 50 行 POJO ──
data class User(
    val id: Long,
    val name: String,
    val email: String? = null,  // 可空类型
    val createdAt: LocalDateTime = LocalDateTime.now()
) {
    val displayName: String
        get() = name.uppercase()
}

// ── 2. 扩展函数:给 String 添加新方法 ──
fun String.isEmail(): Boolean =
    this.matches(Regex("^[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$"))

// ── 3. 密封类:受限层次 + when 穷举 ──
sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

fun <T> Result<T>.getOrDefault(default: T): T = when (this) {
    is Result.Success -> data
    is Result.Error -> default
    Result.Loading -> default
}

// ── 4. 协程:同步写法写异步 ──
suspend fun fetchUser(id: Long): User {
    delay(1000)  // 模拟网络请求,不阻塞线程
    return User(id = id, name = "Alice")
}

// ── 5. 主函数 ──
fun main() = runBlocking {
    // 作用域函数 let
    val email = "alice@example.com"
    email.let { e ->
        println("${if (e.isEmail()) "" else ""} $e")
    }

    // 作用域函数 apply
    val user = User(id = 1, name = "Bob").apply {
        println("创建用户: $displayName")
    }

    // 协程并发
    val deferred1 = async { fetchUser(1) }
    val deferred2 = async { fetchUser(2) }
    val users = listOf(deferred1.await(), deferred2.await())
    users.forEach { println("获取到: ${it.name}") }

    // 使用密封类
    val result: Result<String> = Result.Success("数据加载成功")
    println(result.getOrDefault("默认值"))

    // when 表达式(不需要 break)
    val grade = when (85) {
        in 90..100 -> "A"
        in 80..89 -> "B"
        in 70..79 -> "C"
        else -> "D"
    }
    println("成绩等级: $grade")
}

运行步骤

# build.gradle.kts 添加协程依赖
dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}

# 运行
gradle run

预期输出

✅ alice@example.com
创建用户: BOB
获取到: Alice
获取到: Alice
数据加载成功
成绩等级: B

Java vs Kotlin 对比

Java Kotlin 代码行数减少
POJO + getter/setter data class ~80%
try-catch null ?. ?: ~60%
CompletableFuture 协程 async/await ~50%
switch when 表达式 ~30%

教程

Kotlin 现代 JVM 语言入门教程

第一章:为什么选 Kotlin

Java 已经 28 年了,虽然稳健,但包袱很重。Kotlin 站在 Java 的肩膀上,保留了 JVM 生态全部优势,同时:

  • 少写 40% 代码(data class、类型推断、扩展函数)
  • 消灭 NPE(编译期空安全)
  • 协程原生异步支持
  • 100% Java 互操作(可混合编译)

Android 开发者已基本全面切换 Kotlin;服务端 Spring Boot + Kotlin 也在快速增长。

第二章:空安全

Kotlin 的类型系统区分「可空」和「不可空」:

var a: String = "abc"   // 不可为空
// a = null             // ❌ 编译错误!

var b: String? = "abc"  // 可空
b = null                // ✅ 允许

// 安全调用
println(b?.length)       // null → 不执行

// Elvis 操作符
val len = b?.length ?: 0 // null 时给默认值

// 非空断言(谨慎使用)
println(b!!.length)      // null → NPE 仍会抛

第三章:协程

协程是 Kotlin 的王牌特性——用同步写法写异步代码:

suspend fun fetchData(): String {
    delay(1000)           // 挂起函数,不阻塞线程
    return "data"
}

// 结构化并发
coroutineScope {
    val d1 = async { fetchData() }
    val d2 = async { fetchData() }
    println(d1.await() + d2.await())
}

核心概念:

  • suspend:挂起函数,可在协程中调用
  • launch:启动协程,不关心返回值
  • async:启动协程,返回 Deferred(类似 Future)
  • runBlocking:阻塞等协程完成(测试/入口用)

第四章:作用域函数

函数 对象引用 返回值 典型场景
let it Lambda 结果 可空对象安全操作
run this Lambda 结果 对象配置+计算
apply this 对象本身 对象初始化
also it 对象本身 附加操作(日志)
with this Lambda 结果 对同一个对象的多次操作

第五章:与 Java 互操作

// 调用 Java 库
val list = ArrayList<String>()
list.add("Kotlin")

// Java 代码调用 Kotlin
// 在 Java 中:KotlinClassKt.topLevelFunction();

// @JvmStatic 让 Kotlin 伴生对象方法在 Java 中当静态方法用
// @JvmOverloads 为默认参数生成重载

思考题

  1. Kotlin 的 ?. 和 Optional 各有什么优劣?
  2. 协程和线程是什么关系?一个线程能跑多少协程?
  3. sealed classenum class 有什么区别?何时用哪个?

参考资料

暂无参考文献