gpt4 book ai didi

scala - 初始化顺序在延迟 val 访问时抛出空指针

转载 作者:行者123 更新时间:2023-12-04 20:57:03 24 4
gpt4 key购买 nike

不出所料,下面没有lazy val的初始化顺序会抛出空指针异常

class Foo {
Bar.x // NullPointerException
}

object Bar extends Foo {
val x = 42
}

object Hello extends App {
Bar
}

检查 -Xprint:jvm 输出,并引用@paradigmatic answer ,我们看到这是由于 Foo 的构造函数首先运行并在 Bar.this.x 初始化之前调用 Bar.x() Bar 的构造函数:

  class Foo extends Object {
def <init>(): example.Foo = {
Foo.super.<init>();
Bar.x();
()
}
};

object Bar extends example.Foo {
private[this] val x: Int = _;
<stable> <accessor> def x(): Int = Bar.this.x;
def <init>(): example.Bar.type = {
Bar.super.<init>();
Bar.this.x = 42;
()
}
};

但是,为什么当xlazy 时也会抛出空指针?像这样

object Bar extends Foo {
lazy val x = 42
}

在惰性情况下分析 -Xprint:jvm 输出

  class Foo extends Object {
def <init>(): example.Foo = {
Foo.super.<init>();
Bar.x();
()
}
};
object Bar extends example.Foo {
final <synthetic> lazy private[this] var x: Int = _;
@volatile private[this] var bitmap$0: Boolean = _;
private def x$lzycompute(): Int = {
Bar.this.synchronized(if (Bar.this.bitmap$0.unary_!())
{
Bar.this.x = (42: Int);
Bar.this.bitmap$0 = true
});
Bar.this.x
};
<stable> <accessor> lazy def x(): Int = if (Bar.this.bitmap$0.unary_!())
Bar.this.x$lzycompute()
else
Bar.this.x;
def <init>(): example.Bar.type = {
Bar.super.<init>();
()
}
};

在我看来,由于 bitmap$0 守卫,它应该可以工作

    <stable> <accessor> lazy def x(): Int = if (Bar.this.bitmap$0.unary_!())
Bar.this.x$lzycompute()
else
Bar.this.x;

运行时字段访问器检查 -Xcheckinit 似乎在我的 Scala 2.12.8 机器上很满意,所以为什么 NullPointerExceptionlazy val x

最佳答案

我不认为这个 NPE 与 val 完全相关。检查这个:

class Foo {
Bar.anyMethod
}

object Bar extends Foo {
def anyMethod = ???
}

object Hello extends App {
Bar
}

//java.lang.NullPointerException

Foo 正在尝试在 Bar 上运行构造函数,而 Bar 仍在构建中。这就是您的 Foo 在调用 x 之前所做的事情。

顺便说一句,如果您使用 main 方法将所有内容放入 Hello 中,您将在我的和您的案例中得到 StackOverflow 而不是 NPE。

object Hello {

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

class Foo {
Bar.anyMethod
}

object Bar extends Foo { //<- Bar is like local val now instead of field
def anyMethod= ??? // of package object, so stack is available now.
}

Bar
}

}

关于scala - 初始化顺序在延迟 val 访问时抛出空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56077401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com