gpt4 book ai didi

java - Java 是否保证对外部类的引用持久化?下面的踪迹怎么可能呢?

转载 作者:搜寻专家 更新时间:2023-10-31 20:34:41 25 4
gpt4 key购买 nike

问题

当一个内部类(注意:非静态)被实例化时,它将获得对外部类的引用(在其构造时)。关于此引用的持久性,哪些保证适用于这种情况(如果有)?

详细解释(试图让问题有意义)

考虑这个简单的代码:

public class OuterInnerExample {

private int mInt;

public void startJob() {
InnerRunnable r = new InnerRunnable();
Thread t = new Thread(r);
t.start();
}

private class InnerRunnable implements Runnable {
public void run() {
int localInt = mInt;
System.out.println(localInt);
}
}
}

编译后,如果我们反编译类文件(我使用jad),我们可以观察到InnerRunnable有一个this$0成员,它是对 OuterInnerExample 对象的引用。

这个引用是在 InnerRunnable 的编译器综合构造函数中设置的,在调用 super() 之前(所以这避免了 this$0 可能是 null 当对象在其构造完成之前被使用时,即通过基类)。

InnerRunnable 想要访问 mInt 时,它会使用一个由编译器合成的静态 getter,它将对 OuterInnerExample 的引用作为参数(这将是 this$0)。这个 getter 是 access$100 方法。

作为引用,可以在此处找到反编译的 Java:http://pastebin.com/gr8GB03t .

现在,整个问题是我观察到(但无法解释)类似于以下的堆栈跟踪:

FATAL EXCEPTION: main
java.lang.NullPointerException
at <package.name>.OuterInnerExample.access$100(<line where "class OuterInnerExample" is>
at <package.name>.OuterInnerExample$InnerRunnable.run(<line where "public void run()" is>)

这让我觉得 this$0 那时一定是 null

最佳答案

回答你的问题:作为JLS 8.1.3状态:

When an inner class (whose declaration does not occur in a static context) refers to an instance variable that is a member of a lexically enclosing class, the variable of the corresponding lexically enclosing instance is used.

阅读JLS 17.4.5关于 happens-before 关系:

The default initialization of any object happens-before any other actions (other than default-writes) of a program.

这里的默认初始化是指给字段赋默认值。

由于字段 private int mInt 是原始字段,因此它不能为 null,因此您必须寻找其他地方。

我的猜测是您从这部分开始使用了一些自定义编译器:

private OuterInnerExample$InnerRunnable(OuterInnerExample outerinnerexample)
{
this$0 = outerinnerexample;
super();
}

导致编译时错误。您必须在构造函数的第一行调用 super()

我实际上复制粘贴了您的原始代码并使用 java 1.7 来执行它并且它没有问题地工作所以我们在这里缺少上下文。

关于java - Java 是否保证对外部类的引用持久化?下面的踪迹怎么可能呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20067697/

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