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进行反编译,可以看到内容如下:


这样就验证了我们的猜想。

你可能感兴趣的:(scala中如何实现的lazy变量的懒加载)