0

As I understand it, any variables used within an inner anonymous class (but declared outside of it) are actually passed a copy of their values. There is also a requirement that these outer variables be declared as final, which obviously means that these variables are not meant to be modified.

But is there any kind of work-around to this? Can my anonymous inner class actually modify some variable or object, which I could then use later on in my code (outside of the anonymous class)? Or would the modifications not be seen outside of the anonymous class?

Decoy
  • 317
  • 1
  • 4
  • 7

2 Answers2

3

The behavior you are referring to applies only to local variables or method/catch parameters. You can access and, potentially, modify instance members just fine

public class Example {

    public void method() {
        String localFoo = "local";
        new Object() {
            public void bar() {
                foo = "bar"; // yup
                System.out.println(localFoo); // sure
                localFoo = "bar"; // nope
            }
        };        
    }

    private String foo = "foo";
}

The anonymous Object inner class copies the value of localFoo for use within the println(..) invocation. However, for foo, it's actually "copying" the reference to the Example instance and referencing its foo field.

It's actually equivalent to

Example.this.foo = "bar";
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Thanks for response. If you instantiate this Example object, call method() on it, and then try printing the 'foo' field, it seems that it still remains as 'foo' and not 'bar'. Why is this? – Decoy Dec 26 '14 at 20:58
  • @Decoy You didn't invoke `bar()`. – Sotirios Delimanolis Dec 26 '14 at 20:59
  • Just to be clear, with your example, there is absolutely no way one could modify the localFoo variable in the anonymous class? – Decoy Dec 26 '14 at 21:06
  • @Decoy That's right. The local variable `localFoo` declared in `method` cannot be modified anywhere within the body of the method or the body of the anonymous class, assuming it's being used in the anonymous class. – Sotirios Delimanolis Dec 26 '14 at 21:08
1

Referenced objects do indeed need to be final - however, they can be mutable.

class Holder<T> {
    public T held;
}

public void test() {
    final Holder<String> s = new Holder<>();
    new Runnable () {

        @Override
        public void run() {
            s.held = "Hello;";
        }

    }
}

This is greatly simplified - you would normally use getters and setters for the held value.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213