美文网首页Growing数客联盟
Scala中lazy val的用法

Scala中lazy val的用法

作者: Woople | 来源:发表于2016-10-14 19:34 被阅读678次

    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的用法

        本文链接:https://www.haomeiwen.com/subject/lmngyttx.html