Kotlin 常见坑速查:object/lateinit/return 那些容易踩的坑

Kotlin 常见坑速查:object/lateinit/return 那些容易踩的坑

这篇文章汇总 Kotlin 开发中的高频问题和易错点,方便快速查阅。

1. object 关键字的三种用法

表格

用法 代码 用途
匿名内部类 object : 接口 {} 一次性实现接口
单例对象 object Config {} 全局单例
伴生对象 companion object {} 替代 static
kotlin 复制代码
// 匿名内部类
button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) { }
})

// 单例
object AppConfig {
    var appName = "我的应用"
}

// 伴生对象
class User {
    companion object {
        const val TAG = "User"
        fun create() = User()
    }
}

2. return 规则

kotlin 复制代码
// 普通函数:return 退出函数
fun normal() {
    if (true) return
    println("不会执行")
}

// 表达式体函数:最后一行自动返回
fun add(a: Int, b: Int) = a + b

// Lambda:return 退出外层函数
listOf(1, 2, 3).forEach {
    if (it == 2) return  // 退出整个函数
}

// Lambda:标签 return 只退出 Lambda
listOf(1, 2, 3).forEach {
    if (it == 2) return@forEach
    println(it)
}

3. 标签循环

kotlin 复制代码
// break@outer:跳出指定循环
outer@ for (i in 1..3) {
    for (j in 1..3) {
        if (j == 2) break@outer  // 直接跳出外层循环
    }
}

// continue@outer:跳到外层下一次
outer@ for (i in 1..3) {
    for (j in 1..3) {
        if (j == 2) continue@outer  // 跳到外层下一次
    }
}

4. lateinit vs lazy

表格

特性 lateinit lazy
用途 延迟初始化 惰性求值
适用 var val
适用类型 非基本类型 任何类型
初始化时机 使用前手动赋值 首次访问时自动初始化
kotlin 复制代码
// lateinit:需要手动初始化的场景
lateinit var binding: ActivityMainBinding
fun init() { binding = ... }

// lazy:第一次使用时自动初始化
val viewModel: MainViewModel by viewModels()
val adapter: UserAdapter by lazy { UserAdapter() }

5. const vs val

表格

特性 const val val
编译时机 编译时确定 运行时确定
位置 只能 object/companion 任何地方
性能 更高 稍低
注解用 ✅ 可以 ❌ 不行
kotlin 复制代码
// const val:编译时常量
object Config {
    const val BASE_URL = "https://api.example.com"
}

// val:运行时确定
val timestamp = System.currentTimeMillis()

6. 解构声明

kotlin 复制代码
// 数据类解构
data class User(val name: String, val age: Int)
val (name, age) = User("张三", 25)

// Map 解构
val map = mapOf("A" to 1, "B" to 2)
for ((key, value) in map) { }

// Pair/ Triple
val (a, b) = Pair(1, 2)
val (x, y, z) = Triple(1, 2, 3)

// Lambda 解构(Kotlin 1.1+)
map.mapValues { (key, value) -> "$key -> $value" }

7. 继承 vs 实现

kotlin 复制代码
// 继承类:加括号(调用父构造)
class Student : Person()

// 实现接口:不加括号(接口没构造)
class Runner : Runnable

// 同时继承 + 实现
class StudentAthlete : Person(), Runnable, Serializable

口诀:继承类必须加括号,实现接口不加括号。

8. vararg 可变参数

kotlin

kotlin 复制代码
// 定义
fun printAll(vararg items: String) {
    items.forEach { println(it) }
}

// 调用
printAll("A", "B", "C")

// 数组展开
val array = arrayOf("X", "Y", "Z")
printAll(*array)  // 展开操作符

9. 中缀函数

kotlin 复制代码
// 定义:infix 修饰,成员函数或扩展函数,单参数
infix fun Int.add(other: Int) = this + other

// 调用:可以省略点号
val sum = 1 add 2
val sum2 = 1.add(2)  // 等价

常用内置中缀函数tountildownTo

ini 复制代码
val pair = "key" to "value"
for (i in 0 until 10) { }
for (i in 10 downTo 0) { }

10. 内联函数

kotlin 复制代码
// inline:减少函数调用开销,复制函数体到调用处
inline fun measureTime(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    println("耗时: ${System.currentTimeMillis() - start}ms")
}

注意:内联函数内的 Lambda 不能存储,不能作为变量。

11. Kotlin vs Java 常见对照

表格

Java Kotlin
final 默认就是这个
instanceof is
(Type) obj obj as Type / obj as? Type
static companion object
new Object() Object()(不用 new)
if (obj != null) obj?.let { }
三元运算符 a ? b : c if (a) b else c

12. 常见编译错误

表格

错误 原因 解决
Val cannot be reassigned val 不能重新赋值 改用 var
Type mismatch 类型不匹配 检查类型转换
Unresolved reference 引用错误 检查 import
Nullable type ... 空安全问题 ?.?:
Only safe calls allowed 空的可能 ?.

总结

这份速查表涵盖了 Kotlin 开发中最常见的问题:

  1. object → 三种用法:匿名内部类、单例、伴生对象
  2. return → 大括号必须 return,表达式自动返回,Lambda 用标签
  3. lateinit vs lazy → 手动 vs 自动
  4. const vs val → 编译时常量 vs 运行时
  5. 解构 → 自动分解为多个变量
  6. vararg → 可变参数,用 * 展开
相关推荐
YB137517 小时前
kotlin 关键字expect/actual的作用
kotlin
Android打工仔18 小时前
不要再把 Flow 当作一个容器
android·kotlin
天空之城--1 天前
Android行业一周动态:编码趋势与行业资讯汇总
android·性能优化·架构·kotlin·android jetpack
JMchen2 天前
第 2 篇|Kotlin 进阶 —— 集合、循环与条件表达式
android·kotlin
YB13752 天前
Kotlin 三类关键字
kotlin
撩得Android一次心动2 天前
Jetpack Compose 知识点整理1【个人用】
android·学习·kotlin·android jetpack·compose
ForteScarlet2 天前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
JMchen1232 天前
Cursor高阶玩法:.cursorrules编写与Spec-Driven开发实战,把AI调教成专属结对编程搭档
人工智能·vscode·kotlin·cursor·结对编程·spec-driven·.cursorrules
hai_android3 天前
Kotlin 协程作用域源码剖析
android·kotlin
leluckys3 天前
【KMP】-KMP 项目commonMain、androidMain、iosMain 到底放什么?
kotlin