Question

Consider the following:

public class OuterClass {

    private String attribute = "outer";

    class InnerClass {
        private String attribute = "inner";
        public doSomething() {
            System.out.println(this.attribute);
            System.out.println(OuterClass.this.attribute);

        }
    }

}

The InnerClass is not static and must be created against an instance of it's outer class.

new OuterClass().new InnerClass()

The regular innerclass holds a reference to the outer class in which it was created, that is accessible using Outer.this.myAttribute (particularly useful in this case where there is a "naming colision"


When creating an anonymous innerclass, it's the same: the anonymous innerclass created holds a reference to the outer class, this is why when declaring a predicate inside a method (anonymous method-local innerclass), we can still access, inside the innerclass, the variables of the outerclass without having to declare them final (while we should for variables passed as method parameters.

public class OuterClass {

  // Do not need to be final because the innerclass keeps a reference to the outerclass
  // even if it's an anonymous innerclass, it's still an innerclass
  private String classAttribute = "classAttribute";

  public Runnable doSomething() {

    // Should be final because the variable lives on the stack and the reference to this object
    // must be copied so that the String object is still accessible when the stack frame is destroyed
    final String localVar = "localVar";

    return new Runnable() {
      @Override
      public void run() {
        System.out.println(classAttribute);
        System.out.println(localVar);
      }
    };
  }

}

And finally, we can declare constants in an interface, which are implicitly marked public static final. An object can be a constant. Thus an object created as an anonymous innerclass is a legal constant for an interface.

For exemple, when using Guava, I usually declare in my interface functions and predicates which permits me to leverage the useful Guava functions like Maps.uniqueIndex(...).

public interface AlternativeNameable {

  String getAlternativeName();

  Function<AlternativeNameable,String> GET_ALTERNATIVE_NAME = new Function<AlternativeNameable,String>() {
    @Override
    public String apply(AlternativeNameable input) {
      return input.getAlternativeName();
    }
  };

}

So you may ask yourself what is my question? Here it is:

When declaring an anonymous class as an interface constant (see my last code sample), on which outerclass does the anonymous innerclass holds a reference to?

Was it helpful?

Solution 2

Inner classes of interfaces are implicitly static and as such, do not require reference to outer class.

OTHER TIPS

Fields defined in interfaces always implicitly have the modifiers public static final. It's a constant, and as such it has no associated outer class.

Also, member types of interfaces are implicitly public and static, which holds true for anonymous classes as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top