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

.

+3


source to share


1 answer


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.

+2


source







All Articles