java应该给出关于从内部类分配私有变量的错误消息吗?
我有一些这样的代码:java应该给出关于从内部类分配私有变量的错误消息吗?,java,closures,inner-classes,Java,Closures,Inner Classes,我有一些这样的代码: class Outter { private Bar bar; [...] public update() { provider.doUpdate(new IListenner() { @Override public void onSuccess(Bar bar) { Outter.this.bar = bar; //
class Outter {
private Bar bar;
[...]
public update() {
provider.doUpdate(new IListenner() {
@Override
public void onSuccess(Bar bar) {
Outter.this.bar = bar;
// Here, Outter.this.bar.equals(bar) is false.
}
}
}
[...]
}
我认为这与Java在闭包中捕获变量的方式有关,捕获条引用
,而不是捕获外部
实例引用。如果我写:
Outter self = Outter.this;
self.bar = bar;
它可以工作,迫使Java编译器存储对myOutter实例的引用,而不是对其闭包中的bar
字段的引用
正确的方法可能是在Outter中使用setBar(Bar)
,并从内部类调用它
但是既然它不工作,为什么Java编译器不给出关于它的错误消息呢?当捕获非最终引用时,像条应该是最终的
我使用AndroidStudio 1.2.1.1编译这个,没有在其他上下文中尝试过,不知道AndroidStudio实际上是如何编译Java的。我的JRE似乎是openjdk-7-JRE-headless Debian软件包版本的Java 1.7.07u79-2.5.5-1~deb8u1
您报告的行为听起来很奇怪。首先,我既不能用ECJ也不能用JavaC7复制它。(见附件)
字节码的差异
Outter.this.bar = bar;
及
只是一个额外的astore_2
/aload_2
,它基本上对应于一个no-op
我鼓励你检查你的假设。也许您的Bar.equals
实现有缺陷,这会导致混乱
当捕获非最终引用时,Like bar应该是最终的吗
从这个意义上讲,字段不会被捕获。字段可以从内部类/方法访问,而不是最终的。我的行为不是这样的:你能创建一个吗?我试图像今天早上那样回滚我的代码,但我无法重现。我们是这方面的两个见证人(我打电话给另一个开发人员,在它发生的时候审查我),所以我没有做梦:-请希望有人会发现相同的问题,并找到相同的线程来添加信息:o(在此之前,我们应该忽略这个)o:Bar.equals只是一个例子,但对象实际上是不同的(不同的数据在里面,不同的地址在内存中)我当时正在调试代码。由于我现在无法复制它,我只能想到编译器试图优化某些东西,有时会导致这种情况…:(我是java的新手,所以我不像你那样喜欢阅读编译后的代码^^^^如果你说将其拆分为两个语句有帮助,那么还有其他原因。(也就是说,它与内部类/闭包无关。相信我的话。我在Oracle担任java编译器开发人员:-)有了我答案中的链接和字节码反汇编,我想我已经毫无疑问地证明了这一点。如果你同意,请随意接受答案。我接受答案,因为我无法复制它,而你对它有很多了解;)
Outter self = Outter.this;
self.bar = bar;