首页 > 解决方案 > Scala 类中已初始化变量,但打印的内容为空?

问题描述

object ObjectExample {
  def main(args: Array[String]): Unit = {
    val student = new Student("zhu", 18, "zz")
    println(student.gender)
  }
}

class People(val name: String, val age: Int) {
  println("constructor")
  println(name)
  val gender: String = "male"
  println(gender)
  def this(name1: String) = {  //it is useless in here
    this("ci", 18)
    println("subconstructor")
    println(name)
    println(gender)
  }
}


class Student(name: String, age: Int, val school: String) extends People(name, age){
  println("derived constructor")
  println(name)
  println(school)
  override val gender: String = "female"
  println(gender)
}

gender我认为我已经初始化的第一个,但它打印的是空的。我尝试在Student课堂上覆盖它并打印“女性”。

这是结果,第三行是People什么gender输出

constructor
zhu
null
derived constructor
zhu
zz
female
female

标签: scala

解决方案


Scala 常见问题解答中对此进行了解释-为什么我的抽象或覆盖的 val 为空?

页面引用:

“严格”或“急切”的 val 是没有标记为惰性的。

在没有“早期定义”(见下文)的情况下,严格 val 的初始化按以下顺序完成。

超类在子类之前完全初始化。否则,按申报顺序。自然,当一个 val 被覆盖时,它不会被多次初始化。因此,尽管上面示例中的 x2 似乎在每个点上都定义了,但情况并非如此:在超类的构造过程中,被覆盖的 val 将显示为 null,抽象 val 也是如此。

有一个编译器标志可用于识别这种情况:

-Xcheckinit:向字段访问器添加运行时检查。

Page 还提供了三种解决方案(详见常见问题页面):

  1. 使用惰性 val
  2. 使用早期定义(正如@jwvh 已经建议的那样)
  3. 使用常量值定义

推荐阅读