一、协程:非阻塞式并发编程的革命
协程是Kotlin解决异步编程的核心武器,通过suspend函数和结构化并发机制,彻底改变了传统回调地狱的编码模式。
1. 调度器与线程切换
fun main() = runBlocking {
// 主线程打印
println("Main Thread: ${Thread.currentThread().name}")
// 切换到IO线程执行耗时操作
val result = withContext(Dispatchers.IO) {
println("IO Thread: ${Thread.currentThread().name}")
delay(500) // 模拟网络请求
"Data from Server"
}
// 自动切换回主线程
println("Result: $result on ${Thread.currentThread().name}")
}
关键点:
Dispatchers.Main:Android UI更新专用
Dispatchers.IO:文件/网络操作优化线程池
withContext自动保存/恢复协程上下文
2. 结构化并发控制
fun fetchUserData() = runBlocking {
coroutineScope { // 创建子协程作用域
val deferred1 = async { fetchFromNetwork1() }
val deferred2 = async { fetchFromNetwork2() }
// 并行执行并等待结果
println("User: ${deferred1.await()}, Posts: ${deferred2.await().size}")
}
// 所有子协程完成后才会继续
println("Coroutine Scope Ended")
}
suspend fun fetchFromNetwork1(): String {
delay(1000)
return "John"
}
suspend fun fetchFromNetwork2(): List<String> {
delay(1500)
return listOf("Post1", "Post2")
}
异常处理:
fun safeLaunch() = runBlocking {
try {
coroutineScope {
launch { throw ArithmeticException("Divide by zero") }
}
} catch (e: Exception) {
println("Caught: ${e.message}") // 捕获子协程异常
}
}
二、高阶函数与内联优化
Kotlin将函数作为一等公民的特性,结合内联优化,创造了极致的函数式编程体验。
1. 带接收者的函数类型(DSL构建)
class HtmlBuilder {
fun body(content: () -> Unit) {
println("<body>")
content()
println("</body>")
}
fun div(text: String) = println("<div>$text</div>")
}
fun html(init: HtmlBuilder.() -> Unit): String {
val builder = HtmlBuilder()
builder.init() // 调用扩展函数
return "HTML Generated"
}
fun main() {
html {
body {
div("Welcome to Kotlin DSL")
}
}
}
2. 内联函数消除运行时开销
inline fun measureTime(block: () -> Unit): Long {
val start = System.nanoTime()
block()
return System.nanoTime() - start
}
fun main() {
val duration = measureTime {
(1..1000000).sum() // 不会创建函数对象
}
println("Execution time: ${duration / 1_000_000}ms")
}
跨inline优化:
inline fun <T> lock(lock: Any, crossinline action: () -> T): T {
synchronized(lock) {
return action() // 禁止非局部返回
}
}
三、泛型进阶:型变与约束
Kotlin通过声明处型变和类型投影,解决了Java泛型中令人困惑的协变/逆变问题。
1. 生产者协变(out)
open class Animal {
fun eat() = println("Eating...")
}
class Cat : Animal() {
fun meow() = println("Meow!")
}
// 协变容器
class Box<out T>(private val value: T) {
fun get(): T = value
}
fun main() {
val catBox: Box<Cat> = Box(Cat())
val animalBox: Box<Animal> = catBox // 合法:Cat是Animal的子类
animalBox.get().eat() // 只能调用Animal的方法
}
2. 消费者逆变(in)
class Comparer<in T> {
fun compare(a: T, b: T): Int {
// 实现比较逻辑
return 0
}
}
fun main() {
val animalComparer: Comparer<Animal> = Comparer()
val catComparer: Comparer<Cat> = animalComparer // 合法:可以处理更具体的类型
catComparer.compare(Cat(), Cat())
}
3. 星号投影(类型安全边界)
fun printList(list: List<*>) { // 等价于 List<out Any?>
when (val first = list.firstOrNull()) {
is String -> println("String: $first")
is Int -> println("Int: $first")
else -> println("Unknown type")
}
}
fun main() {
printList(listOf("Kotlin", 42)) // 安全处理未知类型
}
四、密封类:类型安全的模式匹配
密封类构建了受限的类层次结构,配合when表达式实现完美的分支覆盖。
1. 状态机实现
bash
sealed class NetworkState {
object Loading : NetworkState()
data class Success(val data: List<String>) : NetworkState()
data class Error(val message: String) : NetworkState()
}
fun renderState(state: NetworkState) = when (state) {
is NetworkState.Loading -> println("Loading...")
is NetworkState.Success -> println("Data: ${state.data.joinToString()}")
is NetworkState.Error -> println("Error: ${state.message}")
}
fun main() {
renderState(NetworkState.Success(listOf("Item1", "Item2")))
// 添加新状态时编译器会强制修改when分支
}
2. 表达式求值
bash
sealed class Expr {
data class Const(val number: Double) : Expr()
data class Neg(val expr: Expr) : Expr()
data class Plus(val left: Expr, val right: Expr) : Expr()
}
fun eval(expr: Expr): Double = when (expr) {
is Expr.Const -> expr.number
is Expr.Neg -> -eval(expr.expr)
is Expr.Plus -> eval(expr.left) + eval(expr.right)
}
fun main() {
val expression = Expr.Plus(
Expr.Const(10.0),
Expr.Neg(Expr.Const(5.0))
)
println(eval(expression)) // 输出 5.0
}
五、反射:运行时类型分析
Kotlin反射API提供了比Java更简洁的类型信息访问方式。
1. KClass与属性操作
bash
data class User(val name: String, val age: Int)
fun main() {
val userClass = User::class // 获取KClass引用
println("Class name: ${userClass.simpleName}")
// 获取构造函数参数
userClass.primaryConstructor?.parameters?.forEach {
println("Param: ${it.name}, type: ${it.type}")
}
// 创建实例
val user = userClass.constructors.first().call("Alice", 30)
println(user)
}
2. 函数调用
bash
class Calculator {
fun add(a: Int, b: Int) = a + b
}
fun main() {
val calc = Calculator()
val addMethod = Calculator::class.members.first { it.name == "add" }
// 调用方法
val result = addMethod.call(calc, 5, 7) as Int
println("5 + 7 = $result")
}
实战建议
协程调试:使用kotlinx-coroutines-debug库获取详细的协程堆栈信息
泛型边界:优先使用where子句实现多类型约束
密封类扩展:结合sealed interface实现更灵活的层次结构
反射性能:缓存KClass引用避免重复反射操作
这些高级特性共同构成了Kotlin强大的类型系统和并发模型,掌握它们将使你能够编写出更简洁、更安全的现代Kotlin代码。建议通过实际项目逐步实践这些特性,特别注意协程的结构化并发和密封类的类型安全特性。