第03章 Kotlin语言核心特性¶
学习目标:全面掌握Kotlin语言的核心特性,理解其在Android开发中的最佳实践。
预计学习时间:3-5天 实践时间:2天
目录¶
1. Kotlin与Java对比¶
1.1 为什么选择Kotlin¶
| 特性 | Kotlin | Java |
|---|---|---|
| 空安全 | 编译期检查 | 运行时异常 |
| 简洁性 | 减少40%样板代码 | 冗长 |
| 函数式编程 | 一等公民支持 | Java 8+部分支持 |
| 协程 | 原生支持 | 需第三方库 |
| 扩展函数 | 支持 | 不支持 |
| 默认参数 | 支持 | 需重载 |
| 数据类 | 一行定义 | 需手写getter/setter |
| 类型推导 | 强大 | 有限 |
1.2 代码对比示例¶
Java代码:
Java
// Java - 数据类
public class User {
private final String name;
private final int age;
private final String email;
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Getter方法
public String getName() { return name; }
public int getAge() { return age; }
public String getEmail() { return email; }
// equals, hashCode, toString
@Override // @Override重写父类方法
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age &&
Objects.equals(name, user.name) &&
Objects.equals(email, user.email);
}
@Override
public int hashCode() {
return Objects.hash(name, age, email);
}
@Override
public String toString() {
return "User{name='" + name + "', age=" + age + ", email='" + email + "'}";
}
}
// Java - 单例模式
public class DatabaseHelper {
private static DatabaseHelper instance;
private DatabaseHelper() {}
public static synchronized DatabaseHelper getInstance() { // synchronized同步锁,保证线程安全
if (instance == null) {
instance = new DatabaseHelper();
}
return instance;
}
}
Kotlin代码:
Kotlin
// Kotlin - 数据类(一行搞定)
data class User(
val name: String,
val age: Int,
val email: String
)
// Kotlin - 单例模式
object DatabaseHelper {
// 自动线程安全
}
// Kotlin - 空安全
fun greet(user: User?) {
// 安全调用
val name = user?.name ?: "Guest"
println("Hello, $name!")
}
// Kotlin - 扩展函数
fun String.addExclamation(): String = this + "!"
val greeting = "Hello".addExclamation() // "Hello!"
// Kotlin - 默认参数
fun createUser(
name: String,
age: Int = 18,
email: String = ""
): User = User(name, age, email)
// 调用时可以省略默认参数
val user1 = createUser("Alice")
val user2 = createUser("Bob", 25)
val user3 = createUser("Charlie", 30, "charlie@example.com")
2. 空安全系统¶
2.1 可空类型与非空类型¶
Kotlin
// 非空类型(默认)
var name: String = "Alice"
// name = null // 编译错误!
// 可空类型(显式声明)
var nickname: String? = "Ally"
nickname = null // 允许
// 安全调用操作符 ?.
val length = nickname?.length // 如果nickname为null,返回null
// Elvis操作符 ?:
val displayName = nickname ?: "Unknown" // 如果为null,使用默认值
// 非空断言 !!(谨慎使用)
val riskyLength = nickname!!.length // 如果为null,抛出NPE
// 安全转换 as?
val obj: Any = "Hello"
val str: String? = obj as? String // 如果转换失败,返回null
2.2 空安全最佳实践¶
Kotlin
// ✅ 推荐:使用安全调用和Elvis操作符
fun processUser(user: User?) {
val name = user?.name ?: return
val email = user.email ?: throw IllegalArgumentException("Email required")
println("Processing $name with email $email")
}
// ✅ 推荐:使用let进行空检查
user?.let { nonNullUser ->
// 在这个作用域内,nonNullUser是非空的
println(nonNullUser.name)
println(nonNullUser.email)
}
// ✅ 推荐:使用also进行副作用操作
user?.also {
analytics.trackUserView(it.id)
}?.let { process(it) }
// ❌ 避免:滥用非空断言
val length = text!!.length // 危险!
// ❌ 避免:不必要的空检查
if (user != null) {
println(user.name) // 可以用?.let替代
}
2.3 平台类型(与Java互操作)¶
Kotlin
// Java代码返回的可空类型需要特别注意
val javaString: String = javaObject.getString() // 可能运行时NPE
val safeString: String? = javaObject.getString() // 更安全
// 使用@Nullable/@NonNull注解
// Java:
// @NonNull
// public String getName() { ... }
// Kotlin会自动识别
val name: String = javaObject.name // 非空
3. 类型系统与泛型¶
3.1 类型推导¶
Kotlin
// 显式类型声明
val name: String = "Alice"
// 类型推导
val age = 25 // 自动推导为Int
val price = 19.99 // 自动推导为Double
val isActive = true // 自动推导为Boolean
// 复杂类型推导
val users = listOf(
User("Alice", 25),
User("Bob", 30)
) // 自动推导为 List<User>
// 泛型类型推导
fun <T> singletonList(item: T): List<T> = listOf(item)
val stringList = singletonList("hello") // 推导为 List<String>
3.2 泛型进阶¶
Kotlin
// 协变(Covariant)- out
interface Producer<out T> {
fun produce(): T
// 不能消费T
}
val stringProducer: Producer<String> = object : Producer<String> {
override fun produce(): String = "Hello"
}
val anyProducer: Producer<Any> = stringProducer // 允许,因为String是Any的子类
// 逆变(Contravariant)- in
interface Consumer<in T> {
fun consume(item: T)
// 不能生产T
}
val anyConsumer: Consumer<Any> = object : Consumer<Any> {
override fun consume(item: Any) = println(item)
}
val stringConsumer: Consumer<String> = anyConsumer // 允许
// 不变(Invariant)- 默认
interface Container<T> {
fun produce(): T
fun consume(item: T)
}
// 类型投影(Use-site variance)
fun copy(from: Array<out Any>, to: Array<Any>) {
// from是协变的,只能读取
}
fun fill(dest: Array<in String>, value: String) {
// dest是逆变的,只能写入
}
3.3 类型约束¶
Kotlin
// 上界约束
fun <T : Comparable<T>> max(a: T, b: T): T {
return if (a > b) a else b
}
// 多个约束
fun <T> process(item: T) where T : Runnable, T : Serializable {
item.run()
}
// 具体化类型参数(reified)
inline fun <reified T> isInstance(value: Any): Boolean {
return value is T
}
// 使用
val isString = isInstance<String>("hello") // true
val isInt = isInstance<Int>("hello") // false
4. 函数与Lambda¶
4.1 函数定义与特性¶
Kotlin
// 基本函数
fun greet(name: String): String {
return "Hello, $name!"
}
// 单表达式函数
fun greet(name: String): String = "Hello, $name!"
// 默认参数
fun greet(name: String, greeting: String = "Hello"): String {
return "$greeting, $name!"
}
// 命名参数
greet(name = "Alice", greeting = "Hi")
greet(greeting = "Hey", name = "Bob")
// 可变参数
fun sum(vararg numbers: Int): Int {
return numbers.sum()
}
sum(1, 2, 3, 4, 5)
// 展开操作符
val nums = intArrayOf(1, 2, 3)
sum(*nums) // 展开数组
4.2 高阶函数¶
Kotlin
// 函数作为参数
fun processNumbers(
numbers: List<Int>,
transformer: (Int) -> Int
): List<Int> {
return numbers.map(transformer)
}
// 使用
val doubled = processNumbers(listOf(1, 2, 3)) { it * 2 }
// 函数作为返回值
fun createMultiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
val triple = createMultiplier(3)
println(triple(4)) // 12
// 函数类型
val operation: (Int, Int) -> Int = { a, b -> a + b }
4.3 Lambda表达式¶
Kotlin
// 基本Lambda
val sum = { a: Int, b: Int -> a + b }
// 类型推导
val multiply: (Int, Int) -> Int = { a, b -> a * b }
// 单个参数(隐式it)
val square: (Int) -> Int = { it * it }
// 多语句Lambda
val process = { x: Int ->
val doubled = x * 2
val result = doubled + 10
result // 最后一行是返回值
}
// 集合操作中的Lambda
val numbers = listOf(1, 2, 3, 4, 5)
// filter
val evens = numbers.filter { it % 2 == 0 }
// map
val squares = numbers.map { it * it }
// reduce
val sum = numbers.reduce { acc, i -> acc + i }
// fold
val product = numbers.fold(1) { acc, i -> acc * i }
// groupBy
val grouped = numbers.groupBy { it % 2 }
// sortedBy
val sorted = numbers.sortedByDescending { it }
// takeWhile
val firstThree = numbers.takeWhile { it < 4 }
4.4 作用域函数¶
Kotlin
// let - 转换对象,返回Lambda结果
val nameLength = user.name?.let {
it.uppercase()
it.length
}
// run - 执行代码块,返回Lambda结果
val result = user.run {
println("Processing $name")
process(this)
name.length
}
// with - 对对象执行多个操作
with(user) {
println(name)
println(email)
updateLastSeen()
}
// apply - 配置对象,返回对象本身
val dialog = AlertDialog.Builder(context).apply {
setTitle("Confirm")
setMessage("Are you sure?")
setPositiveButton("Yes") { _, _ -> }
setNegativeButton("No", null)
}.create()
// also - 执行副作用,返回对象本身
val file = File("data.txt").also {
println("Creating file: ${it.name}")
it.createNewFile()
}
// 对比总结
// let/run/with: 返回Lambda结果
// apply/also: 返回接收者对象
// let/also: 使用it
// run/apply/with: 使用this
5. 协程与异步编程¶
5.1 协程基础¶
Kotlin
import kotlinx.coroutines.*
// 启动协程
fun main() = runBlocking {
// launch - 启动新协程,不阻塞,返回Job
val job = launch {
delay(1000L)
println("World!")
}
println("Hello,")
job.join() // 等待协程完成
// async - 启动新协程,返回Deferred(可获取结果)
val deferred = async {
delay(1000L)
"Result"
}
val result = deferred.await() // 获取结果
println(result)
}
// 协程作用域
class MyViewModel : ViewModel() {
fun fetchData() {
viewModelScope.launch {
// 在ViewModel作用域中启动协程
// 当ViewModel清除时自动取消
}
}
}
// 自定义作用域
val scope = CoroutineScope(Dispatchers.Main + Job())
scope.launch {
// 在自定义作用域中执行
}
// 取消作用域
scope.cancel()
5.2 调度器(Dispatchers)¶
Kotlin
// Dispatchers.Main - 主线程(UI操作)
launch(Dispatchers.Main) {
updateUI()
}
// Dispatchers.IO - 磁盘/网络IO
launch(Dispatchers.IO) {
val data = fetchFromNetwork()
}
// Dispatchers.Default - CPU密集型任务
launch(Dispatchers.Default) {
val result = heavyComputation()
}
// Dispatchers.Unconfined - 不限制,从调用线程开始
launch(Dispatchers.Unconfined) {
// 特殊用途,一般不使用
}
// 切换调度器
launch(Dispatchers.Main) {
val data = withContext(Dispatchers.IO) {
// 在IO线程执行
fetchData()
}
// 回到主线程
displayData(data)
}
5.3 Flow - 响应式流¶
Kotlin
import kotlinx.coroutines.flow.*
// 创建Flow
val numberFlow: Flow<Int> = flow {
for (i in 1..5) {
delay(100)
emit(i) // 发射值
}
}
// 收集Flow
lifecycleScope.launch {
numberFlow.collect { value ->
println(value)
}
}
// Flow操作符
val processedFlow = numberFlow
.map { it * it } // 转换
.filter { it > 10 } // 过滤
.onEach { println("Processing: $it") } // 副作用
.catch { e -> println("Error: $e") } // 错误处理
.flowOn(Dispatchers.IO) // 指定执行调度器
// StateFlow - 状态流(热流)
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun updateState(newState: UiState) {
_uiState.value = newState
}
}
// SharedFlow - 共享流(热流)
class EventBus {
private val _events = MutableSharedFlow<Event>()
val events = _events.asSharedFlow()
suspend fun emit(event: Event) {
_events.emit(event)
}
}
// 在Compose中收集
@Composable
fun MyScreen(viewModel: MyViewModel) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
// 使用uiState更新UI
}
5.4 异常处理¶
Kotlin
// try-catch
launch {
try {
riskyOperation()
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
// SupervisorJob - 子协程失败不影响其他
val supervisor = SupervisorJob()
val scope = CoroutineScope(Dispatchers.Main + supervisor)
scope.launch {
// 子协程1
launch {
throw Exception("Failed")
}
// 子协程2 - 继续执行
launch {
delay(100)
println("Still running")
}
}
// CoroutineExceptionHandler
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
val scope = CoroutineScope(Dispatchers.Main + handler)
scope.launch {
throw Exception("Error")
}
// Flow异常处理
flow {
emit(1)
throw Exception("Error")
emit(2)
}.catch { e ->
println("Caught: $e")
emit(-1) // 发射默认值
}.collect {
println(it)
}
6. 面向对象与函数式编程¶
6.1 类与继承¶
Kotlin
// 基本类
open class Person(
val name: String,
var age: Int
) {
open fun introduce() {
println("I'm $name, $age years old")
}
}
// 继承
class Student(
name: String,
age: Int,
val school: String
) : Person(name, age) {
override fun introduce() {
super.introduce()
println("I study at $school")
}
}
// 数据类
data class User(
val id: String,
val name: String,
val email: String = "" // 默认参数
) {
// 自动获得:equals, hashCode, toString, copy, componentN
}
// 使用数据类
val user1 = User("1", "Alice")
val user2 = user1.copy(name = "Bob") // 复制并修改
val (id, name, email) = user1 // 解构
// 密封类(Sealed Class)
sealed class Result<out T> {
data class Success<T>(val data: T) : Result<T>() // 泛型<T>:类型参数化
data class Error(val exception: Exception) : Result<Nothing>()
object Loading : Result<Nothing>()
}
// 使用密封类
fun handleResult(result: Result<String>) {
when (result) {
is Result.Success -> println("Data: ${result.data}")
is Result.Error -> println("Error: ${result.exception}")
Result.Loading -> println("Loading...")
}
}
// 枚举类
enum class Status {
PENDING,
PROCESSING,
COMPLETED,
FAILED;
fun isTerminal() = this == COMPLETED || this == FAILED
}
// 带属性的枚举
enum class Priority(val value: Int) {
LOW(1),
MEDIUM(2),
HIGH(3)
}
6.2 接口与抽象类¶
Kotlin
// 接口
interface Drawable {
fun draw()
fun resize() { // 默认实现
println("Default resize")
}
}
interface Clickable {
fun click()
}
// 实现多个接口
class Button : Drawable, Clickable {
override fun draw() {
println("Drawing button")
}
override fun click() {
println("Button clicked")
}
}
// 解决冲突
class CustomView : Drawable, Clickable {
override fun draw() {
super<Drawable>.resize() // 调用指定接口的默认实现
}
override fun click() {}
}
// 抽象类
abstract class Shape {
abstract fun area(): Double
fun printArea() {
println("Area: ${area()}")
}
}
class Circle(val radius: Double) : Shape() {
override fun area(): Double = Math.PI * radius * radius
}
6.3 函数式编程特性¶
Kotlin
// 不可变性
val immutableList = listOf(1, 2, 3)
// immutableList.add(4) // 错误!
val mutableList = mutableListOf(1, 2, 3)
mutableList.add(4) // 允许
// 纯函数
fun pureAdd(a: Int, b: Int): Int = a + b // 无副作用,相同输入总是相同输出
// 不可变数据操作
val numbers = listOf(1, 2, 3, 4, 5)
// 不改变原列表,返回新列表
val doubled = numbers.map { it * 2 }
val evens = numbers.filter { it % 2 == 0 }
val sum = numbers.fold(0) { acc, n -> acc + n }
// 函数组合
fun <A, B, C> compose(
f: (B) -> C,
g: (A) -> B
): (A) -> C = { x -> f(g(x)) }
val addOne = { x: Int -> x + 1 }
val double = { x: Int -> x * 2 }
val addOneThenDouble = compose(double, addOne)
println(addOneThenDouble(3)) // (3 + 1) * 2 = 8
// 部分应用(Partial Application)
fun <A, B, C> ((A, B) -> C).partial(a: A): (B) -> C {
return { b -> this(a, b) }
}
fun add(a: Int, b: Int) = a + b
val addFive = ::add.partial(5)
println(addFive(3)) // 8
// 柯里化(Currying)
fun <A, B, C> ((A, B) -> C).curry(): (A) -> (B) -> C {
return { a -> { b -> this(a, b) } }
}
val curriedAdd = ::add.curry()
val addTen = curriedAdd(10)
println(addTen(5)) // 15
7. DSL构建¶
7.1 类型安全构建器¶
Kotlin
// HTML DSL示例
abstract class Tag(val name: String) {
val children = mutableListOf<Tag>()
val attributes = mutableMapOf<String, String>()
protected fun <T : Tag> initTag(tag: T, init: T.() -> Unit): T {
tag.init()
children.add(tag)
return tag
}
override fun toString(): String {
val attrs = if (attributes.isEmpty()) ""
else attributes.map { "${it.key}='${it.value}'" }.joinToString(" ", " ")
val content = children.joinToString("")
return "<$name$attrs>$content</$name>"
}
}
class HTML : Tag("html") {
fun head(init: Head.() -> Unit) = initTag(Head(), init)
fun body(init: Body.() -> Unit) = initTag(Body(), init)
}
class Head : Tag("head") {
fun title(init: Title.() -> Unit) = initTag(Title(), init)
}
class Title : Tag("title") {
operator fun String.unaryPlus() {
children.add(Text(this))
}
}
class Body : Tag("body") {
fun h1(init: H1.() -> Unit) = initTag(H1(), init)
fun p(init: P.() -> Unit) = initTag(P(), init)
}
class H1 : Tag("h1") {
operator fun String.unaryPlus() {
children.add(Text(this))
}
}
class P : Tag("p") {
operator fun String.unaryPlus() {
children.add(Text(this))
}
}
class Text(private val text: String) : Tag("") {
override fun toString() = text
}
fun html(init: HTML.() -> Unit): HTML {
val html = HTML()
html.init()
return html
}
// 使用DSL
val document = html {
head {
title { +"My Page" }
}
body {
h1 { +"Welcome" }
p { +"This is a DSL example" }
}
}
println(document)
// 输出: <html><head><title>My Page</title></head><body><h1>Welcome</h1><p>This is a DSL example</p></body></html>
7.2 Gradle Kotlin DSL¶
Kotlin
// build.gradle.kts
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose") // Kotlin 2.0+ Compose 编译器插件
}
android {
namespace = "com.example.app"
compileSdk = 35
defaultConfig {
applicationId = "com.example.app"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
buildFeatures {
compose = true
}
// Kotlin 2.0+ 无需 composeOptions,Compose 编译器版本由 kotlin.plugin.compose 插件管理
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.compose.ui:ui:1.5.4")
// 使用lambda配置依赖
val composeBom = platform("androidx.compose:compose-bom:2024.02.01")
implementation(composeBom)
androidTestImplementation(composeBom)
}
7.3 Compose UI DSL¶
Kotlin
// Jetpack Compose就是Kotlin DSL的完美示例
@Composable
fun MyScreen(viewModel: MyViewModel = hiltViewModel()) {
val uiState by viewModel.uiState.collectAsState()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = "Hello, ${uiState.userName}!",
style = MaterialTheme.typography.headlineMedium
)
Button(
onClick = { viewModel.onRefresh() },
modifier = Modifier.fillMaxWidth()
) {
Text("Refresh")
}
when {
uiState.isLoading -> CircularProgressIndicator()
uiState.error != null -> ErrorMessage(uiState.error)
else -> ContentList(uiState.items)
}
}
}
8. Kotlin 2.0与K2编译器¶
8.1 K2编译器简介¶
Kotlin 2.0于2024年发布,引入了全新的K2编译器(代号K2),这是Kotlin编译器的重大重构版本。K2编译器带来了显著的性能提升和语言特性增强。
主要改进¶
| 特性 | 改进幅度 | 说明 |
|---|---|---|
| 编译速度 | 提升94% | 编译Kotlin代码速度比原始编译器快近2倍 |
| 代码分析 | 大幅提升 | 高亮、补全、查找跳转速度显著改善 |
| 内存占用 | 降低 | 编译过程中内存使用效率更高 |
| 新语言特性 | 全面支持 | 支持Kotlin 2.0及以上版本的新特性 |
启用K2编译器¶
在Android Studio Narwhal(2025.1.1)及更高版本中,K2模式已成为默认选项:
Kotlin
// gradle.properties
kotlin.experimental.tryK2=true
// 或者在build.gradle.kts中
kotlin {
compilerOptions {
languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0
}
}
8.2 Kotlin 2.0新特性¶
数据类的copy函数改进¶
Kotlin
// Kotlin 2.0之前 - 需要复制所有属性
data class User(
val name: String,
val age: Int,
val email: String
)
val user = User("Alice", 30, "alice@example.com")
val updatedUser = user.copy(age = 31) // 其他属性保持不变
// Kotlin 2.0 - 支持在copy中使用命名参数
// 现在可以在copy中更灵活地处理默认值
枚举类中的数据对象¶
Kotlin
// Kotlin 2.0支持在密封类和枚举中使用数据对象
sealed interface Error // interface定义类型契约
// 数据对象自动生成equals/hashCode/toString
data object NetworkError : Error
data object DatabaseError : Error
data class ValidationError(val field: String) : Error
更好的类型推导¶
Kotlin
// Kotlin 2.0改进了类型推导
val list = buildList {
add("hello") // 自动推导为MutableList<String>
add("world")
}
// Lambda返回类型推导改进
val transform = when (condition) {
true -> { x: Int -> x * 2 }
false -> { x: Int -> x + 1 }
} // 编译器能正确推导类型
8.3 Android Studio集成¶
Android Studio Narwhal(2025.1.1)及更高版本默认启用K2模式:
注意事项: - K2编译器与旧编译器在边缘情况下可能有不同行为 - 某些第三方插件可能需要更新以兼容K2 - 建议在项目升级前进行充分测试
8.4 迁移指南¶
从Kotlin 1.9迁移到2.0的步骤:
-
更新Gradle插件:
-
更新编译器选项:
-
检查破坏性变更:
- 某些反射API的行为可能有变化
- 类型推导的改进可能导致之前编译通过的代码需要调整
9. 实践练习¶
练习1:空安全重构¶
任务:将以下Java代码重构为Kotlin,确保空安全
Java
public class UserManager {
private User currentUser;
public String getUserDisplayName() {
if (currentUser != null) {
if (currentUser.getProfile() != null) {
return currentUser.getProfile().getDisplayName();
}
}
return "Guest";
}
public void updateEmail(String newEmail) {
if (currentUser != null && newEmail != null) {
currentUser.setEmail(newEmail);
}
}
}
要求: - 使用Kotlin的空安全特性 - 使用Elvis操作符和安全调用 - 减少代码行数
练习2:泛型容器实现¶
任务:实现一个类型安全的Result容器类
Kotlin
sealed class Result<out T> {
// 实现Success和Error子类
// 实现map、flatMap、getOrElse等方法
}
// 使用示例
fun fetchUser(id: String): Result<User> {
return try { // try/catch捕获异常
val user = api.getUser(id)
Result.Success(user)
} catch (e: Exception) {
Result.Error(e)
}
}
// 链式操作
fetchUser("123")
.map { it.name }
.getOrElse { "Unknown" }
练习3:协程实践¶
任务:实现一个并行数据加载器
Kotlin
class DataLoader {
suspend fun loadUserData(userId: String): UserData {
// 并行加载用户基本信息、订单、设置
// 使用async和await
// 处理异常
}
}
// 测试
runBlocking {
val data = DataLoader().loadUserData("123")
println(data)
}
练习4:DSL设计¶
任务:设计一个网络请求DSL
Kotlin
// 目标DSL
val request = httpRequest {
url = "https://api.example.com/users"
method = HttpMethod.GET
headers {
"Authorization" to "Bearer token"
"Content-Type" to "application/json"
}
queryParams {
"page" to "1"
"limit" to "10"
}
}
// 实现DSL构建器
本章小结¶
核心要点¶
- 空安全是Kotlin的核心特性,通过编译期检查避免NPE
- 类型系统强大且灵活,支持泛型、类型推导和类型投影
- 函数是一等公民,支持高阶函数、Lambda和函数式编程
- 协程简化异步编程,Flow提供响应式数据流
- DSL构建能力使Kotlin成为构建领域特定语言的理想选择
Kotlin vs Java速查¶
| Java | Kotlin |
|---|---|
User user = new User() | val user = User() |
user.getName() | user.name |
user.setName("Alice") | `user.name = "Alice" |
if (obj instanceof String) | if (obj is String) |
(String) obj | obj as String |
switch | when |
System.out.println() | println() |
final | val |
new Thread(() -> {}).start() | thread { } |
try-catch-finally | try-catch-finally 或 use |
下一步¶
完成本章学习后,请进入第04章:Jetpack Compose UI框架详解,开始学习现代Android UI开发。
参考资源¶
官方文档¶
学习资源¶
进阶阅读¶
本章完成时间:预计3-5天