当前位置: 首页 > news >正文

这2个代码 找做网站的 安装一下网站文章页要不要做内链

这2个代码 找做网站的 安装一下,网站文章页要不要做内链,做热饮店网站,网站建设电子书资料Scala中使用关键字lazy来定义惰性变量#xff0c;实现延迟加载(懒加载)。 惰性变量只能是不可变变量#xff0c;并且只有在调用惰性变量时#xff0c;才会去实例化这个变量。 在Java中#xff0c;要实现延迟加载(懒加载)#xff0c;需要自己手动实现。一般的做法是这样的…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关键字修饰变量后只有在使用该变量时才会调用其实例化方法。也就是说在定义propertyinitProperty()时并不会调用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)}}上面的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() 在声明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;}}原理探究 scala也是编译成字节码跑在jvm上的而jvm的字节码指令并没有提供对lazy这种语义的支持所以由此可以推断lazy只是一个语法糖scala编译器在编译时期对其做一些包装转换但究竟是如何转换的呢可以写一段代码编译然后反编译看一下。 编写一段scala代码有两个变量一个使用lazy修饰一个不使用lazy修饰 package cc11001100.scala.lazyStudyclass LazyInitDemoForDecompilation {lazy val foo fooval bar bar }object LazyInitDemoForDecompilation {def main(args: Array[String]): Unit {val o new LazyInitDemoForDecompilation()println(o.foo)println(o.bar)}}然后编译为字节码文件再使用jd-gui等工具将其反编译 package cc11001100.scala.lazyStudy;import scala.reflect.ScalaSignature;ScalaSignature(bytes\006\001}2A!\003\006\001#!)q\003\001C\0011!A1\004\001EC\002\023\005A\004C\004\001\t\007I\021\001\017\t\r\031\002\001\025!\003\036\017\0259#\002#\001)\r\025I!\002#\001*\021\0259b\001\\001\021\025Yc\001\\001-\005qa\025M_J]$H)Z7p\r\024H)Z2p[BLG.\031;j_:T!a\003\007\002\0231\f0_*uk\022L(BA\007\017\003\025\0318-\0317b\025\005y\021AC2dcE\002\004M\0311a\r\0011C\001\001\023!\t\031R#D\001\025\025\005i\021B\001\f\025\005\031\te.\037*fM\0061A(\0338jiz\\022!\007\t\0035\001i\021AC\001\004M|W#A\017\021\005y\031S\A\020\013\005\001\n\023\001\0027b]\036T\021AI\001\005U\0064\030-\003\002%?\t11\013\036:j]\036\f1AY1s\003\021\021\027M\035\021\00291\0130_%oSR$U-\\8G_J$UmY8nad\027\r^5p]B\021!DB\n\003\rI!\022\001K\001\005[\006Lg\016\006\002.aA\0211CL\005\003_Q\021A!\0268ji\)\021\007\003a\001e\005!\021M]4t!\r\0312N\005\003iQ\021Q!\021:sCf\004\AN\037\017\005]Z\004C\001\035\025\033\005I$B\001\036\021\003\031a$o\\8u}%\021A\bF\001\007!J,G-\0324\n\005\021r$B\001\037\025\001) public class LazyInitDemoForDecompilation {private String foo;private String foo$lzycompute(){// 因为在调用此方法之前已经判断过一次标志位的值了// 所以可以看做是一种被拆散了的DCLsynchronized (this){if (!this.bitmap$0){this.foo foo;this.bitmap$0 true;}}return this.foo;}public String foo(){// 每次获取foo的值的时候先判断是否已经初始化过了// 如果还没有初始化就将其初始化否则直接将已经计算出的值返回return !this.bitmap$0 ? foo$lzycompute() : this.foo;}public String bar(){return this.bar;}// bar变量直接为其赋值的private final String bar bar;// 这个变量是一个标志位用来记录foo变量是否已经被初始化过了private volatile boolean bitmap$0;public static void main(String[] paramArrayOfString){LazyInitDemoForDecompilation..MODULE$.main(paramArrayOfString);} }在object中执行 package cc11001100.scala.lazyStudy;import scala.Predef.;public final class LazyInitDemoForDecompilation$ {public static MODULE$;static{new ();}public void main(String[] args){LazyInitDemoForDecompilation o new LazyInitDemoForDecompilation();// 会将对变量的访问替换成调用访问器// 这样的话编译器就可以很鸡贼的在访问器方法中插入各种处理以提供N多的语法糖挺机智的Predef..MODULE$.println(o.foo());Predef..MODULE$.println(o.bar());}private LazyInitDemoForDecompilation$(){MODULE$ this;} } 综上源码得出结论scala的lazy关键字就是编译器在编译期将变量的初始化过程替换为Double Check Lock类似于Java中的懒汉式单例模式初始化。 Scala同样使用了Java中常用的懒加载的方式自动帮助我们实现了延迟加载并且还加锁避免多个线程同时调用初始化方法可能导致的不一致问题。 对于这样一个表达式 lazy val t:T expr 无论expr是什么东西字面量也好方法调用也好。Scala的编译器都会把这个expr包在一个方法中并且生成一个flag来决定只在t第一次被访问时才调用该方法。
http://www.w-s-a.com/news/3366/

相关文章:

  • 网站刷链接怎么做成都高度网站技术建设公司
  • flash网站模板怎么用xml网站地图生成
  • 英文网站优化群晖wordpress中文
  • saas建站平台源码济南品牌网站建设公司
  • 网站建设一般是用哪个软件网站百度
  • 企业建站的作用是什么南宁公司网站开发
  • 厦门网站建设及维护门户网站开发视频教学
  • 可以做兼职的网站有哪些自动点击器永久免费版
  • 建购物网站怎么建呀网站怎么做中英文交互
  • 网站建设费用计入无形资产做网站用的主机
  • 佛山企业网站建设平台沈阳网站建设培训班
  • 河南企业网站优化外包网站怎么做来流量
  • 网站建设的参考文献网站设计网页的优缺点
  • WordPress多站點支付插件内江市网站建设培训
  • 做做网站已更新动漫制作专业需要学什么
  • dfv印花图案设计网站网站建设应该应聘什么岗位
  • 网站后台管理系统模板下载专业网站推广的公司哪家好
  • 克拉玛依市建设局网站网页设计板式重构
  • 网站新闻专题怎么做湖南营销型网站建设 要上磐石网络
  • 阿里云发布网站成都轨迹公布
  • php网站源码架构谷歌站群系统
  • 潮州网站seowordpress 调用置顶文章
  • 做带会员后台的网站用什么软件旅游网站建设资金请示
  • 商品网站怎么做wordpress 表情拉长
  • 商城网站设计费用网络公司怎样推广网站
  • 视频公司的网站设计工图网
  • 免费快速网站十八个免费的舆情网站