Scala中lazy val的用法

lazy修饰变量就是为了延迟初始化

When a val is declared as lazy, its initialization is deferred until it is accessed for the first time.

  • 场景一
    在类的初始化的时候可能某个变量初始化比较耗时,那么可以使用lazy,等真正使用到这个变量的时候再初始化
scala> class Person{
     |   val properties = {
     |     //模拟长时间的某种操作
     |     println("init")
     |     Thread.sleep(2000)
     |   }
     | }
defined class Person

scala> def main() {
     |   println("Start")
     | 
     |   val startTime = System.currentTimeMillis()
     |   val person = new Person
     |   val endTime = System.currentTimeMillis()
     | 
     |   println("End and take " + (endTime - startTime) + "ms")
     | 
     |   person.properties
     | }
main: ()Unit

scala> main
Start
init
End and take 2002ms

可以看到new了一个对象,需要大约2000ms,如果改成lazy变量

scala> class Person{
     |   lazy val properties = {
     |     //模拟长时间的某种操作
     |     println("init")
     |     Thread.sleep(2000)
     |   }
     | }
defined class Person

scala> main
Start
End and take 0ms
init

new操作几乎瞬间完成,而且在真正使用变量的时候才初始化的

  • 场景二
    构造顺序问题
trait Person{
  val name: String
  val nameLen = name.length
}

class Student extends Person{
  override val name: String = "Tom"
}

如果这时候在main函数中new一个Student,会报空指针异常
这是因为父类的constructor先与子类执行,那么在执行val nameLen = name.length的时候name还没有被赋值,所以才会导致空指针。
解决办法就是在nameLen前加lazy,延迟初始化

lazy val nameLen = name.length
  • 缺点
    每次使用前都会检查是否已经初始化,会有额外的开销,并没有那么高效。

你可能感兴趣的:(Scala中lazy val的用法)