Static Nested, Inner, Anonymous and Method Local Inner Classes

Reading Time: 6 minutes

While I was studying for 1z0-804 OCP certification exam, I’ve come to learn something that I had been really curious for a long while; defining such local classes named nested and inner classes which I never really quite learnt how they work and their intentions. So as of today I’ve fully apprehend the whole thing and written a simple example code that fully works.

OuterClass.java

public class Outer {

    class InnerClass {

        void localInnerNonStatic() {
            class LocalInner {
            }
        }

        Object anonymousNonStatic() {
            return new Object() {
                public String toString() {
                    return "anonymous";
                }
            };
        }
    }

    static class NestedClass {
        void localInnerNonStatic() {
            class LocalInner {
            }
        }

        static void localInnerStatic() {
            class LocalInner {
            }
        }

        Object anonymousNonStatic() {
            return new Object() {
                public String toString() {
                    return "anonymous";
                }
            };
        }

        static Object anonymousStatic() {
            return new Object() {
                public String toString() {
                    return "anonymous";
                }
            };
        }
    }
}

Type of inner class                                                                          Description
Static or static nested class                                                                Is a static member of its enclosing class and can access all the static variables and members of its outer class

Inner or member class                                                                        Is an instance member of its enclosing class. It can access all the instance and static members of its outer class, including private members.

Method local inner class                                                                    Is defined within a method. Local inner classes are local to a method. They can access all the members of a class, including its private members, but they can be accessed only within the method in which                                                                                                                      they’re defined.

Anonymous                                                                                            inner class Is a local class without a name

1. Nested Classes

When you create a static nested class, it’s compiled as a separate class file. The .class file for a static nested file includes the name of its outer class. On compiling the code shown in the preceding example, the compiler generates two .class files, Outer.class and Outer$StaticNested.class.

Outer.java

class Outer {
    static int outerStatic = 10;
    int outerInstance = 20;

    static class StaticNested {
        static int innerStatic = 10;
        int innerInstance = 20;
    }

    public static void main(String args[]) {
        StaticNested nested1 = new StaticNested();
        Outer.StaticNested nested2 = new Outer.StaticNested();
        nested1.innerStatic = 99;
        nested1.innerInstance = 999;
        System.out.println(nested1.innerStatic + ":" + nested1.innerInstance);
        System.out.println(nested2.innerStatic + ":" + nested2.innerInstance);
    }
}

javac Outer.java

ls -la

-rw-r–r– 1 taslan 1049089 389 Oct 14 10:30 ‘Outer$StaticNested.class’
-rw-r–r– 1 taslan 1049089 965 Oct 14 10:30 Outer.class
-rw-r–r– 1 taslan 1049089 506 Oct 14 10:29 Outer.java

java Outer
Picked up JAVA_TOOL_OPTIONS: -Duser.language=de
99:999
99:20

Accessing members of a static nested class

public class Outer1 {
    
    public static void main(String[] args) {
        System.out.println(new Outer.StaticNested().innerInstance);
        System.out.println(Outer.StaticNested.innerStatic);
    }

}

Access levels of a static nested class

A static nested class can be defined using all access levels: private, default access, protected, and public. The accessibility of the static nested class depends on its access modifier. For example, a private static nested class can’t be accessed outside its outer class. The access of a static nested class also depends on the accessibility of its outer class. If the outer class is defined with the default access, an inner nested class with public access won’t make it accessible outside the package in which its outer class is defined.

Members of outer class accessible to static nested methods

class Outer {
    static int outerStatic = 10;
    int outerInstance = 20;

    public static class StaticNested {
        //outerStatic is accessible
        static int innerStatic = outerStatic;
        int innerInstance = outerStatic;
        //outerInstance is not accessible
        static int innerStatic = outerInstance;
        int innerInstance = outerInstance;
    }
}

2. Inner Classes

The definition of an inner class is enclosed within another class, also referred to as an outer class. An inner class is an instance member of its outer class. An instance of an inner class shares a special bond with its outer class and can’t exist without its instance.

You’d usually create an inner class to encapsulate partial functionality of your main class such that the existence of the inner class instance isn’t possible without its outer class instance. This is in contrast to a nested static class, which can be used without an
instance of its outer class. For example, the following code defines a class Tree and an inner class TreeSort. Tree defines operations to add, remove, and sort objects based on a condition. Instead of defining methods and variables to sort the tree elements within class Tree, it encapsulates sorting functionality within class TreeSort.

class Node {
Object value;
Node left, right;
}
class Tree {
Tree() {}
Node rootNode;
void addElement(Object value) {
//.. code //
}
void removeElement(Object value) {
//.. code //
}
void sortTree(boolean ascending) {
new TreeSort(ascending).sort();
}
class TreeSort{
boolean ascendingSortOrder = true;
TreeSort(boolean order) {
ascendingSortOrder = order;
}
void sort() {
// outer class’s rootNode and sort tree values
// sorting code can be complex
}
}
}

CHARACTERISTICS OF INNER CLASSES
Because an inner class is a member of its outer class, an inner class can be defined using any of access modifiers. Like a regular top-level class, an inner class can also define constructors, variables, and methods.

class Outer {

	protected class Inner {
		Inner() {
		}

		public String publicInner = "Inner";
		private int privateInner = 10;
		final static int finalStaticInner = 1;
		// static int staticInner = 10;
		// static void staticMethod(){}
	}

}

 

CREATION OF AN INNER CLASS

Whenever you instantiate an inner class, remember that an instance of an inner class
can’t exist without an instance of the outer class in which it’s defined. Let’s look at creating
an inner class:
1.Within an outer class, as an instance member,
2.Within a method of an outer class,
3.Within a static method of an outer class,
4.Outside the outer class.

 

1.

class Outer {
  Inner objectInner = new Inner();
  class Inner {}
}

2.

class Outer {
   Inner in = new Inner();
   class Inner {}
   void aMethod () {
      Inner objectInner = new Inner();
   }
}

3.

public class Outer {

	class Inner {}

	static void staticMethod(){
//THE BELOW LINE OF CODE WILL NOT COMPILE
//		Inner staticInner = new Inner();
		Outer outer = new Outer();
		Inner innerObject = outer.new Inner();
		Inner innerObject2 = new Outer().new Inner();
	}
}

4.

public class Foo {
// THE BELOW LINE OF CODE WILL NOT COMPILE
//	Inner inner;
	Outer.Inner inner;

	public Foo() {
		Outer outer = new Outer();
// tHE BELOW LINE OF CODE WILL NOT COMPILE
//		inner = outer.new Inner();
		inner = outer.new Inner();
	}
	
	static void staticFoo(){
		Outer outer = new Outer();
		Outer.Inner innerStatic = outer.new Inner();
	}
	
}

WHAT CAN AN INNER CLASS ACCESS?
An inner class is a part of its outer class. Therefore an inner class can access all variables and methods of an outer class, including its private members and the ones that it inherits from its base classes. An inner class can also define members with the same
name as its outer class

class Outer
	private String privateOuter = "Outer";
	private int sameName = 20;
	class Inner{
		String publicInner = privateOuter;
		int sameName = Outer.this.sameName;
	}
}

3. Anonymous Classes

As the name implies, an anonymous inner class isn’t defined using an explicit name. An anonymous inner class is created when you combine instance creation with inheriting a class or implementing an interface. Anonymous classes come in handy when you
wish to override methods for only a particular instance. They save you from defining new classes. The anonymous class might override none, few, or all methods of the inherited class. It must implement all methods of an implemented interface.

CONTENT WILL BE WRITTEN FROM MY NOTES

4. Method local inner classes

The method local inner classes are defined within static or instance methods of a class. Though these classes can also be defined within code blocks, they are typically created within methods. So their discussion will be limited to their creation in methods. Figure
2.15 shows the definition of a bare-bones method local inner class, Inner, defined within method outerMethod() of class Outer. The Java compiler generates separate class files for the classes Outer and Inner. Because a class can define method local inner classes with the same name in separate methods, the Java compiler adds a number to the name of the compiled file for the local inner classes.

CONTENT WILL BE WRITTEN FROM MY NOTES

Some content materials were depicted from Mala Gupta’s OCP Book