Classes can be defined inside of other classes; these are called inner classes. Fundamentally inner classes are the same as any other class except that they are defined inside the body of another class. For example: public class Outer { public class Inner { private int i; public void myMethod(){ … } } } Scope An inner class defined outside a method belongs to the class and has class scope (similar to member variables). Instances of the inner class can be created in any method of the outer class. Inner classes can also be defined inside a method; an inner class declared inside a method belongs to the method and has local (method) scope (similar to automatic variables). That method can create instances of that class, but other methods of the outer class cannot see this inner class. Inner classes defined inside a method have some limitations: They cannot be declared with an access modifier They cannot be declared static Inner classes with local scope can only access variables of the enclosing method that are declared final, referring to a local variable of the method or an argument passed into the enclosing method Inner classes have full visibility to their outer classes' variables and methods. Listing 6.7 demonstrates this. Listing 6.7 Outer.java public class Outer { private int a = 5; public class Inner { private int i=1; public void myMethod() { System.out.println( "a=" + a + ", i=" + i ); } } public static void main( String[] args ) { Outer.Inner innerClass = new Outer().new Inner(); innerClass.myMethod(); } } The inner class, Inner, can access its own member variable i as well as the outer class Outer's member variable a, even though it is private. Access Modifiers Because inner classes defined outside a method behave similar to member variables, the access modifier that you choose to assign to that class controls whether that class can be accessed outside of the outer class. If you declare the inner class to be public, it can be accessed by prefixing the inner class name with the outer class name. An instance of the outer class must exist for this to be possible. For example: Outer outer = new Outer(); Outer.Inner inner = o.new Inner() Or: Outer.Inner inner = new Outer().new Inner(); Static Inner Classes Inner classes, such as class variables and methods, can be declared to be static. Because they are static, they are not associated with an instance of an outer class. This means that you can create an instance of the inner class without having to create an instance of the outer class. Static inner classes have some limitations regarding accessing the outer class's methods: Listing 6.8 demonstrates these two limitations. Listing 6.8 OuterTest.java public class OuterTest { public static int outerInt = 5; public static class StaticInner { public static int doubleVal( int n ) { System.out.println( "outerInt=" + outerInt ); return 2*n; } } public void testInner() { int a = 5; System.out.println( "a=" + a + ", doubleVal=" + StaticInner.doubleVal( a ) ); } public static void main( String[] args ) { int n = 7; System.out.println( "n=" + n + ", doubleVal=" + OuterTest.StaticInner.doubleVal( n ) ); OuterTest out = new OuterTest(); out.testInner(); } } The inner class, StaticInner, accesses the outer class OuterTest's static variable outerInt in the doubleVal method call. If outerInt was not defined to be static, the StaticInner class could not access it. The main method demonstrates that you do not need to create an instance of the outer class to access a static inner class when it makes the following call: OuterTest.StaticInner.doubleVal( n ) Anonymous Inner Classes There is a category of inner classes that will be discussed extensively in Chapter 14, "Event Delegation Model," called anonymous classes. They have the following properties: Chapter 14 will show a complete example demonstrating common usage. |