Should java give an error about assigning a private variable from inner classes?
I have a code like this:
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.
}
}
}
[...]
}
I think it has to do with the way Java captures the variables in my closure, capturing bar reference
instead of capturing the instance reference Outer
. If I write:
Outter self = Outter.this;
self.bar = bar;
it works by forcing the Java compiler to store a reference to mine Outter instance
instead of a field reference bar
in its closure.
The correct way to do this is probably to use setBar(Bar bar)
in Outter and call it from the inner class.
But since that won't work, why isn't the Java compiler reporting this error message? How about bar should be final
capturing a non-final link?
I will compile this with Android Studio 1.2.1.1, haven't tried it in other contexts, don't know how Android Studio actually compiles Java. My JRE seems to be Java 1.7.0 from the openjdk-7-jre-headless version of the Debian package 7u79-2.5.5-1~deb8u1
.
source to share
The behavior you are reporting sounds very strange. First, I cannot reproduce it with either ECJ or javac 7. (See http://ideone.com/B4CoQs )
Difference between bytecode between
Outter.this.bar = bar;
and
Outter self = Outter.this;
self.bar = bar;
is just an optional astore_2
/ aload_2
which basically matches no-op.
I recommend that you check your assumptions. Perhaps you have a flawed implementation Bar.equals
that is causing confusion.
As with the ending of the link as the final link, should the bar be final?
Fields are not captured in this sense. Fields can be obtained from inner classes / methods without being final.
source to share