0
点赞
收藏
分享

微信扫一扫

【错误记录】Kotlin 代码运行时报错 ( 在 init 初始化块中调用还未初始化的成员属性 )


文章目录

  • ​​一、报错信息​​
  • ​​二、问题分析​​
  • ​​三、解决方案​​



该问题的本质就是 , 成员属性 在 init 初始化代码块中进行初始化 , 但是在初始化之前调用了该 成员属性 , 编译时没有报错信息 , 但是运行时会报异常 ;






一、报错信息


执行如下代码 :

class Hello {
var name: String
fun nameFirstLetter() = name[0]
init {
println(nameFirstLetter())
name = "Tom"
}
}

fun main() {
Hello()
}

执行结果 :

Exception in thread "main" java.lang.NullPointerException
at Hello.nameFirstLetter(Hello.kt:3)
at Hello.<init>(Hello.kt:5)
at HelloKt.main(Hello.kt:11)
at HelloKt.main(Hello.kt)

Process finished with exit code 1



上述代码在编译时 , 没有报错 ;

【错误记录】Kotlin 代码运行时报错 ( 在 init 初始化块中调用还未初始化的成员属性 )_java






二、问题分析


从 初始化 角度分析 上述代码的执行顺序 , Kotlin 类 对象在实例化 时会执行一系列的 初始化操作

  • 主构造函数
  • 类中的属性赋值
  • init 初始化块
  • 次构造函数


首先 , 上述代码中没有主构造 函数 , 因此该项忽略 ;

然后 , 执行属性的赋值 , 代码中定义了 name 属性 , 但是没有进行赋值 ;

var name: String

再后 , 执行 init 初始化块 , 其中先执行 ​​nameFirstLetter​​​ 函数 , 在该函数中调用了 ​​fun nameFirstLetter() = name[0]​​ 中的 name 属性 , 但是 name 属性还没有赋值 , 因此爆出了空指针异常 ;

init {
println(nameFirstLetter())
name = "Tom"
}



该问题的本质就是 , 成员属性 在 init 初始化代码块中进行初始化 , 但是在初始化之前调用了该 成员属性 , 编译时没有报错信息 , 但是运行时会报异常 ;






三、解决方案


调换 初始化代码块 中的代码顺序 , 先给 name 成员赋值 , 然后再执行 调用 name 成员的方法 ;

class Hello{
var name: String
fun nameFirstLetter() = name[0]
init {
name = "Tom"
println(nameFirstLetter())
}
}

fun main() {
Hello()
}


举报

相关推荐

JAVA: 初始化块

0 条评论