posted 19 years ago
A nested class is a class defined as a member of another class. Its type is Enclosing.Nested (and its filename is Enclosing$Nested.class). If a nested class is non-static, then it is an "inner" class, because it can only be created "inside" an instance of the enclosing class.
In a static context (that is, with no "this" reference to an instance of the enclosing class), any new instance of the inner class must be explicitly tied to a particular instance of the enclosing class. This can be done in two ways:
Enclosing.Inner x = new Enclosing().new Inner();
-or-
Enclosing x = new Enclosing();
Enclosing.Inner y = x.new Inner();
However, in the context of an implicit "this" reference to an instance of the enclosing class (that is, within an instance method of the enclosing class), inner class objects can also be created as follows (where "new" is implicitly this.new):
Enclosing.Inner x = new Inner();
Note that multiple instances of the inner class can be created with a single instance of the enclosing class.
So, in this case...
A a1 = new A(); A new instance of A is created and assigned to a1. In creating this object, static variables "counter" and "innerCounter" are both initialized to 0; then in A's constructor, an instance variable "name" is set to "A0", and "counter" is incremented to 1.
new A().new B(); First, another new instance of A is created. Using the same static variable "counter", a new instance variable "name" is set to "A1", and "counter" is incremented to 2. Next, an instance of A.B is created as an inner object associated with the instance of A just created. In B's constructor, a different instance variable "name" -- this one restricted to the scope of the inner class -- is set to "B0", and innerCounter is incremented to 1. The print statement outputs A's "name" (A1) followed by B's "name" (B0).
new A.B(); Here, a new instance of A.B is created without creating a new instance of A. Instead, the enclosing instance is the object referenced by a1 ("this" in m2). In B's constructor, another instance variable "name" is set to "B1", and innerCounter is incremented to 2. The print statement outputs a1's "name" (A0) followed by B's "name" (B1).
new B(); This is essentially a shorthand version of above. Another instance of A.B is created, also associated with the instance of A referenced by a1 ("this" in m3). In B's constructor, another instance variable "name" is set to "B2", and innerCounter is incremented to 3. The print statement outputs a1's "name" (A0) followed by this B's "name" (B2).
[ September 06, 2005: Message edited by: marc weber ]
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org