1

Following is from Effective Java:

The association between a nonstatic member class instance and its enclosing instance is established when the former is created; it cannot be modified thereafter. Normally, the association is established automatically by invoking a nonstatic member class constructor from within an instance method of the enclosing class. It is possible, although rare, to establish the association manually using the expression enclosingInstance.new MemberClass(args). As you would expect, the association takes up space in the nonstatic member class instance and adds time to its construction.

What is Bloch saying here by "It is possible, although rare, to establish the association manually using the expression enclosingInstance.new MemberClass(args). As you would expect, the association takes up space in the nonstatic member class instance and adds time to its construction." ?

Geek
  • 26,489
  • 43
  • 149
  • 227

1 Answers1

5

He means you can establish the connection in at least two ways. Given

public class Outer {
    public class Inner {
    }
    void f() {System.out.println(new Inner());}
}
Outer x = new Outer();

If you call

x.f()

then the value you print is an inner object linked to x.

But one can also invoke:

x.new Inner();

to create a new inner object linked to x as well.

Bloch is saying the second way is rare. I'm not sure why; I have used it in the past.

See a live demo

class Outer {
    String name;
    public Outer(String name) {
        this.name = name;
    }

    public class Inner {
        public String toString() {
            return "I belong to " + Outer.this.name;
        }
    }

    void f() {
        System.out.println(new Inner());
    }

    void g(Outer a) { 
        System.out.println(a.new Inner());
    }
}

class Main {
    public static void main(String[] args) {
        Outer x = new Outer("x");
        Outer y = new Outer("y");
        x.f();
        x.g(y);      
    }
}

Output:

I belong to x
I belong to y
Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • 9
    It's rare because *usually* the `Inner` instance will be created somewhere *inside* `Outer`, so the simpler syntax `new Inner()` is used instead. The reason this is the more common case is that an inner class is usually *strongly bound* to its inner instance and is not usually interesting to other objects. – Joachim Sauer Jul 19 '12 at 08:26
  • @JoachimSauer even if we use the second approach then also "the inner class will be strongly bound to its inner instance " isn't it ? – Geek Jul 19 '12 at 08:37
  • @Geek: I'm talking more about the architectural/logical view here as opposed to the purely technical view. In the technical sense you are absolutely correct: the resulting object will be indistinguishable in both cases. But from a logical view the `Outer` class would not "want" other classes to touch (or even *create*) `Inner` objects. – Joachim Sauer Jul 19 '12 at 08:41
  • @JoachimSauer thanks for the clarification..+1. I have edited the answer with your comment. – Geek Jul 19 '12 at 08:42
  • I've used the Outer.new Inner() construct plenty for unit testing the inner class. It's the case that application code rarely has to construct a non-static Inner class (you need a damn good reason to do so, as IMHO it's breaking with the Outer's encapsulation). – maasg Jul 19 '12 at 08:43