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
- 缺点
每次使用前都会检查是否已经初始化,会有额外的开销,并没有那么高效。
网友评论