You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中非基本类型触发NullPointerException,基本类型却正常?求解

Kotlin初始化顺序引发的空指针疑惑
open class Vehicle {    
    inner class Engine {
        var specs: String = ""
        constructor() {
            specs = getSpecs()
        }
    }
    val engine = Engine()
    open fun getSpecs(): String {
        return ""
    }
}
class Bike: Vehicle() {
    private val model: Model = Model("APACHE", "YAMAHA")
    private val year = 2024
    override fun getSpecs(): String {
        return "Model: \${model.company} - \${model.modelName}. Year: \$year"
    }
}
data class Model(
    val modelName: String,
    val company: String
)

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Model.getCompany()" because "this.model" is null

创建Bike实例时会抛出上述空指针异常,我明白异常的基本原因,但有个疑惑:如果在getSpecs方法里只保留对year的调用,去掉model.company和model.modelName的调用,程序就能正常运行。既然此时year也还没完成初始化,为什么不会触发异常?


核心原因是Kotlin中引用类型和基本数据类型的初始化默认值规则不同,再结合类的初始化顺序:

  1. 类初始化顺序逻辑:创建Bike实例时,会先执行父类Vehicle的初始化逻辑。父类里的engine属性优先初始化,调用Engine的构造方法后,会触发getSpecs方法——这个方法已经被子类Bike重写,实际执行的是Bike的getSpecs实现。
  2. 成员变量初始化状态差异:
    • model是引用类型(Model对象),Kotlin中引用类型成员变量的默认初始值为null。此时调用model.company,本质是对null对象调用方法,必然触发空指针异常。
    • year是基本数据类型(Int),Kotlin中基本数据类型的成员变量有默认初始值(Int默认值为0)。虽然此时year还没被赋值为2024,但它已经有了合法的默认值,直接使用不会出现空指针,程序可正常运行。

内容的提问来源于stack exchange,提问作者Abhilash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:53:19