scala中如何實現的lazy變量的懶加載

lazy關鍵字可以用來修飾不可變變量,該關鍵字的作用是:當對象被真正使用的時候才會被初始化。經常用于一些可能用到也可能用不到的情形,例如:創建一個Connection對象,或者自定義一個可能用到的函數。

lazy的底層編譯是如何實現的?

以最簡單的如下代碼為例:

class Goo {

????lazy val goo = "hello"

}

用scalac進行編譯之后,再用jad進行反編譯,結果如下:

public class Goo {

????public static void main(String args[]) {

????????Goo$.MODULE$.main(args);

????}

????private String goo$lzycompute() {

????????synchronized(this) {

????????????if(!bitmap$0) {

????????????????goo = "hello";

????????????????bitmap$0 = true;

????????????}

????????}

????????return goo;

????}

????public String goo() {

????????return bitmap$0 ? goo : goo$lzycompute();????

????}

????public Goo() { }

????private String goo; private volatile boolean bitmap$0;

}

從編譯的角度來看,lazy的實現基本就是用一個異步方法包裝的,很類似我們日常在Java中封裝了一個方法,在方法中實現了對象的實例化。從而避免對象直接實例化。那么可以推測,在實際使用lazy變量goo的時候,實際使用的,是調用的goo()方法。

我們在代碼中加點內容驗證一下:

class Goo { lazy val goo = "hello"}

object Goo {

? ??def main(args: Array[String]): Unit = {

? ??????val o = new Goo()

? ??????print(o.goo)

? ? }

}

然后對Goo.scala進行編譯之后,會產生Goo.class和Goo$.class。

我們對Goo$.class進行反編譯,可以看到內容如下:


這樣就驗證了我們的猜想。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容