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编译器存储对my
Outter实例的引用,而不是对其闭包中的
bar
字段的引用

正确的方法可能是在Outter中使用
setBar(Bar)
,并从内部类调用它

但是既然它不工作,为什么Java编译器不给出关于它的错误消息呢?当捕获非最终引用时,像
条应该是最终的


我使用AndroidStudio 1.2.1.1编译这个,没有在其他上下文中尝试过,不知道AndroidStudio实际上是如何编译Java的。我的JRE似乎是openjdk-7-JRE-headless Debian软件包版本的Java 1.7.0
7u79-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;