【scala】Scala中lazy关键字的使用和理解
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关键字的使用和理解 作者:br0x 转载仅为方便学习查看,一切权利属于原作者,如果带来不便请联系我删除. Scala中 ...
- scala语言示例_var关键字与Scala中的示例
scala语言示例 Scala var关键字 (Scala var keyword) The var Keyword in scala is used to declare variables. As ...
- scala中def_def关键字以及Scala中的示例
scala中def Scala def关键字 (Scala def keyword) The def keyword in Scala is used to declare functions and ...
- scala方法中的变量_Scala中的变量
scala方法中的变量 Scala变量 (Scala variables) A variable is named a reference to a memory location. The loca ...
- scala不使用new关键字创建对象实例
在scala中,scala不使用new关键字创建对象实例,一般有2中方法: 1. 为类创建伴生对象,并在伴生对象内按照所需的构造函数签名定义一个apply方法: 2.将类定义为case类. 1)用ap ...
- scala 函数中嵌套函数_Scala合成函数
scala 函数中嵌套函数 Scala中的合成功能 (Composition function in Scala) Scala composition function is a way in whi ...
- scala 类中的对象是类_Scala中的类和对象
scala 类中的对象是类 Scala中的课程 (Classes in Scala) A class is a blueprint for objects. It contains the defin ...
- scala 类中的对象是类_Scala类和对象– Singleton对象,伴侣类
scala 类中的对象是类 Earlier we learned about Scala Programming Language and it's installation on Windows a ...
- scala方法中的变量_Scala变量,变量范围,字段变量,方法参数示例
scala方法中的变量 Variables can be defined as the reserve space in memory to store the assigned values. Ba ...
最新文章
- 华为手机如何升级鸿蒙系统_华为杨海松:明年所有华为自研设备升级鸿蒙系统...
- Educational Codeforces Round 2 B. Queries about less or equal elements
- Python---json模块
- 分布式锁-常用技术方案
- c语言通讯录运行结果,自己改编的通讯录,运行不行啊
- Github|类别不平衡学习资源(上)
- git常用命令,项目删除原有github连接并重新连接,回滚,下拉分支代码,切换分支
- 常用不等式及证明思路总结(一)
- django模板-通过a标签生成链接并跳转
- 股票市值高好还是低好呢?
- 学计算机高考分数线,2020高考分数线预测
- Matlab中的有限域计算
- BUUCTF Crypto [HDCTF2019]together wp
- 解析美团联盟,美团分销联盟,美团福利宝,外卖美天赚区别和玩法
- 有效id和密码_ID和密码恢复
- 安卓修改软件安装时间_[地质勘察]理正工程地质勘察CAD9.0PB3软件安装教程
- 数据库---四中连接查询(交叉、左连接、右连接、完整查询)
- 循环冗余校验-CRC
- 【JS】1126- 如何更好的取消一个promise?
- 嵌入式系统开发期末复习
热门文章
- 支付宝支付--新手快速入手(十分钟上手)
- 情不知所起,而一往情深,对于技术上的追求,遥远而又临近。创业艰难,也很容易中道崩阻。拭目以待的产品该何去何从。分享一些前端跟随的创业之路过程。漫漫长路随风而行。
- 用门面模式讲一个浪漫的爱情故事,实现一场美好的婚礼
- 豆瓣 TOP3 的 Python 书,千万别错过
- Spring自动装配的常用方式
- python爬虫系列—— requests和BeautifulSoup库的基本用法
- MorphVOX Pro v4.3.21 语音聊天变化你声音
- 【postman 发送不成功问题与解决】
- Nginx——Nginx缓存集成
- mysql输入01变成1_01-MySQL基本操作