【scala】Scala中lazy关键字的使用和理解
来源:互联网 发布:什么网络游戏mac可以玩 编辑:程序博客网 时间:2024/06/04 18:00
Scala中使用关键字lazy来定义惰性变量,实现延迟加载(懒加载)。
惰性变量只能是不可变变量,并且只有在调用惰性变量时,才会去实例化这个变量。
在Java中,要实现延迟加载(懒加载),需要自己手动实现。一般的做法是这样的:
public class LazyDemo { private String property;public String getProperty() { if (property == null) {//如果没有初始化过,那么进行初始化 property = initProperty(); } return property;} private String initProperty() { return "property"; }}
比如常用的单例模式懒汉式实现时就使用了上面类似的思路实现。
而在scala中对延迟加载这一特性提供了语法级别的支持:
lazy val property = initProperty()
使用lazy关键字修饰变量后,只有在使用该变量时,才会调用其实例化方法。也就是说在定义property=initProperty()时并不会调用initProperty()方法,只有在后面的代码中使用变量property时才会调用initProperty()方法。
如果不使用lazy关键字对变量修饰,那么变量property是立即实例化的:
object LazyOps { def init(): String = { println("call init()") return "" } def main(args: Array[String]) { val property = init();//没有使用lazy修饰 println("after init()") println(property) }}
- 1
上面的property没有使用lazy关键字进行修饰,所以property是立即实例化的,如果观察程序的输出:
call init()after init()
可以发现,property声明时,立即进行实例化,调用了`init()“实例化方法
而如果使用lazy关键字进行修饰:
object LazyOps { def init(): String = { println("call init()") return "" } def main(args: Array[String]) { lazy val property = init();//使用lazy修饰 println("after init()") println(property) println(property) }}
观察输出:
after init()call init()
- 1
在声明property时,并没有立即调用实例化方法intit(),而是在使用property时,才会调用实例化方法,并且无论缩少次调用,实例化方法只会执行一次。
与Java相比起来,实现懒加载确实比较方便了。那么Scala是如何实现这个语法糖的呢?反编译看下Scala生成的class:
private final String property$lzycompute$1(ObjectRef property$lzy$1, VolatileByteRef bitmap$0$1) { synchronized (this)//加锁 { if ((byte)(bitmap$0$1.elem & 0x1) == 0)//如果属性不为null {//那么进行初始化 property$lzy$1.elem = init();bitmap$0$1.elem = ((byte)(bitmap$0$1.elem | 0x1)); } return (String)property$lzy$1.elem; } }
- 1
Scala同样使用了Java中常用的懒加载的方式自动帮助我们实现了延迟加载,并且还加锁避免多个线程同时调用初始化方法可能导致的不一致问题。
借鉴崔鹏飞的小结
对于这样一个表达式: lazy val t:T = expr 无论expr是什么东西,字面量也好,方法调用也好。Scala的编译器都会把这个expr包在一个方法中,并且生成一个flag来决定只在t第一次被访问时才调用该方法。
转载自:http://blog.csdn.net/bing2011/article/details/52104216
- 【scala】Scala中lazy关键字的使用和理解
- Scala中lazy关键字的使用和理解
- scala 特性之一 lazy关键字
- scala的lazy
- Scala惰性赋值:lazy的使用
- Scala lazy
- scala中extends和with的使用
- scala学习笔记:理解lazy值
- SCALA中this关键字
- scala-04For与Function进阶实战、Lazy的使用
- scala-04For与Function进阶实战、Lazy的使用
- Scala学习第四天 Scala的For与Function进阶实战、Lazy的使用
- Scala学习第四天 Scala的For与Function进阶实战、Lazy的使用
- Scala的sealed关键字
- Scala基础—异常、Lazy使用示例
- Scala中Case的使用
- scala中yield的使用
- scala中function的使用
- sql server如何对表进行查看锁和解锁
- SIGABRT的可能原因
- 颜色格式转换: 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)
- Java基础面试题
- Mac OS X系统下adb调试Android手机的方法
- 【scala】Scala中lazy关键字的使用和理解
- PHP开发增删改查
- IE浏览器下ajax缓存导致数据不更新的解决方法
- PathUtil
- windows10专业版许可证到期 激活方法
- Java与垃圾回收技术类型的学习思考
- 一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现......
- 【Android Develop Tips】BindService/StartService
- 利用 Docker 包 Laradock 服务器部署 Laravel & ThinkSNS+ 等程序实战(多项目)