|
Brief tutorial on Java Inner classes |
|
|
Written by marc castrovin
|
|
Page 2 of 2
Instantiating Non-Static Member Inner Class Objects
- Before you can instantiate a non-static member inner class object, you must first instantiate an enclosing class object
- From within a non-static method in the enclosing class, you can use normal new operator syntax
- From outside, you use new along with the reference to the enclosing class object
Inside enclosing class non-static method
InnerClass2 m2 = new InnerClass2();
Outside of an enclosing class non-static method
MyEnclosingClass m = new MyEnclosingClass();
MyEnclosingClass.InnerClass2 m2 = m.new InnerClass2();
Non-static member inner classes are considered to part of an enclosing class INSTANCE, not of the enclosing class itself (static inner classes ARE considered part of the enclosing class). Therefore, the enclosing class instance must first exist before you can create an instance of the inner class.
Again, the syntax is different depending on where you are trying to instantiate the inner class object. From within an enclosing-class, non-static method, there's an implicit "this" for the enclosing class, so you can use the normal "new" syntax. From anywhere else, you need to use the rather odd "new" syntax that uses the dot operator following the reference to the enclosing class instance.
Introduction to Local Inner Classes
- Local inner classes are defined within the boundary of a method
- The local class is only visible within the method that defines it
- Local class methods can access enclosing class fields and method local variables defined as final
- There are two categories of local inner classes: named and anonymous

The key difference between local inner classes and the two categories we've already covered is that local inner classes reside within a method, rather than being a member of the enclosing class itself.
Named Local Inner Classes
- Named local inner classes are defined within the boundary of a method and are only visible within that method
1 public class MyEnclosingClass
2 {
3 public void anotherMethod()
4 {
5 class Inner4
6 {
7 private int x = 17;
8
9 public void myMethod()
10 {
11 System.out.println(x);
12 }
13 }
14 }
15 . . .
16 }
Named local inner classes reside within a method and are considered part of the method. They are useful if you need a one-off class just for use by a single method.
Note that you cannot use "public" or "private" modifiers on the inner class definition, since such modifiers are only allowed on members defined at class scope.
Accessing Enclosing Class Members
- Named local inner classes can access any enclosing class field or method and method local variables defined as final
1 public class MyEnclosingClass
2 {
3 . . .
4 public void anotherMethod()
5 {
6 int z = 44;
7 final int q = 32;
8 class Inner4
9 {
10 private int x = 17;
11 public void myMethod()
12 {
13 System.out.println(x);
14 System.out.println(q);
15 System.out.println(MyEnclosingClass.this.x);
16 }
17 }
18 . . .
19 }
Named local inner classes have basically the same access to fields as do non-static member inner classes, but there's a twist: local inner classes can also access local variables defined in the method in which they reside. Caveat: The local variables must use the final modifier, which means they are constant, and greatly reduces the usefulness of this technique.
Instantiating Named Local Inner Class Objects
- Since named local inner classes are only visible within the method that defined them, you can use normal new operator syntax
1 public class MyEnclosingClass
2 {
3 . . .
4 public void anotherMethod()
5 {
6 class Inner4
7 {
8 public void myMethod()
9 {
10 . . .
11 }
12 }
13
14 Inner4 m5 = new Inner4();
15 m5.myMethod();
16 }
17 }
Since local inner classes are only visible from within the method that encloses them, you instantiate and use objects typed to the inner class within the enclosing method.
Intro to Anonymous Local Inner Classes
- Anonymous local inner classes are defined within the boundary of an enclosing class method
- The definition of an anonymous inner class is a Java expression, not a complete statement, so it can reside within an expression (e.g. a call to a method)
- Anonymous inner classes can reference a superclass or a super-interface -- if you specify a super-interface, Object is the implicit superclass
Anonymous inner classes might seem a bit weird at first -- how can you define a class without naming it? But they are quite useful, especially in GUI applications. You do have to get used to the syntax, however.
Writing and Instantiating an Anonymous Local Inner Class
- An anonymous class can reference a superclass -- Java implicitly defines a new class with the specified fields and methods
1 public class MyEnclosingClass
2 {
3 public void anotherMethod2()
4 {
5 System.out.println (new Object()
6 {
7 private int x = 17;
8 public String toString()
9 {
10 return "Inner x: " + x +
11 " Enclosing x: " + MyEnclosingClass.this.x;
12 }
13 } );
14 }
15 . . .
16 }
For anonymous inner classes, you define the class and instantiate an object all in one step.
Note that we defined the inner class within a call to System.out.println -- it's a common scenario to define anonymous classes within method calls, especially registration calls for JavaBean events.
In this case, we subclassed Object and override toString() -- remember that System.out.println() automatically calls toString() on any object references passed.
Anonymous inner classes have the same access to enclosing class members and final local variables as do named local inner classes.
Anonymous Local Inner Class and Interfaces
- Instead of referencing a superclass, you can specify a super-interface -- Java implicitly defines a new class that subclasses Object and implements the interface
- You will need to include all interface methods in the anonymous inner class!
1 public class MyEnclosingClass
2 {
3 public void anotherMethod3()
4 {
5 System.out.println (new java.io.Serializable()
6 {
7 public String toString()
8 {
9 return "Hello";
10 }
11 } );
12 }
13 . . .
14 }
In this case, we defined an anonymous inner class that subclasses Object and implements the java.io.Serializable interface (which is a tagging interface with no methods).
It does look odd to use the "new" operator on an interface!
|