Nested Inner ClassesJ8 Home « Nested Inner Classes

In the Nested Static Member Classes lesson we took our first look at inner classes by looking at static inner classes. In this lesson we take a first look at non-static nested classes, which are known as inner classes. There are different types of inner class and we will look at inner and local inner classes in this lesson and the different types of anonymous inner class in the Nested Anonymous Inner Classes lesson.

Inner Classes Top

A nested class that is associated with an instance of its outer class, is known as an inner class. An inner class has access to all the methods and variables associated with the instance of the outer class including members with the private access modifier and can only exist within an outer instance.

the heap 10

There are three types of inner class, a non-static member class, which is a member of the outer class, just like the instance variables and methods are. The other two types are known as local inner classes and anonymous inner classes which exist within a method of the outer class. We will look at member inner classes first and then look at the inner classes associated with a method.

Non-static Member Classes Top

This type of inner class is a member of the outer class just like instance variables and methods are and as such the same modifiers and rules apply as to any member. We can instantiate a non-static member class as part of the outer class state or seperately when you don't want all outer instances to have an inner instance.

  • Using non-static member classes is very useful when we require a class that doesn't pass the IS-A test but is intrinsicly associated with its enclosing class.
  • A non-static member class is a member of a class just like any other member and as such can have the same modifers applied in its class declaration: these being abstract, final, private, protected, public, static and strictfp.
    • Of course using the static keyword in the class declaration means we have turned the non-static member class into a static member class and so no longer have access to any instance variables and methods.
  • If the class is required by other classes as well, then the class would be better suited as a standard top-level class instead.

On-demand Example Top

Following is code to create a non-static member class instance from a method or from outside the class as required:


package info.java8;
/*
  A Top-level Class
*/ 
public class Outer {
    private String a;
    
    public void createInner() {
        Inner inner = new Inner(); // Create inner class instance
        inner.changeInstanceVariables(); // Call inner class method
    }
    /*
      Non-static member class
    */ 
    class Inner {
         int b;
         void changeInstanceVariables() {
             a = "Updated";
             b = 1234;
             System.out.println("Outer variable a = " + a + ". Inner variable b = " + b); 
             System.out.println("Outer reference = " + Outer.this + ". Inner reference = " + this); 
         }
    }
}

Save and compile the file in directory   c:\_ObjectsAndClasses in the usual way. Lets write a new test class for our Outer class.


package info.java8;
/*
  Test Class for Outer
*/ 
public class OuterTest {

    public static void main (String[] args) {
        Outer outer = new Outer();
        outer.createInner();
        /*
          Create inner class from outside the class
        */ 
        Outer outer2 = new Outer();
        Outer.Inner inner2 = outer2.new Inner();
        inner2.changeInstanceVariables();
    }
}

Save, compile and run the file in directory   c:\_ObjectsAndClasses in the usual way.

run outer test

The above screenshot shows the output of running our OuterTest class. We create an inner class by calling the createInner() method as and when we require the inner class. The second example shows the syntax for instantiating an inner class from outside the outer class and calling a method of the inner class. We also show the syntax for accessing the currently executing object using the this keyword for the outer and inner objects and print this off.

Always Instantiated Example Top

Ok, now lets look at code to instantiate a non-static member class as part of the outer class object state for those occasions when we always want an inner object attached to the outer object.


package info.java8;
/*
  A Top-level Class
*/ 
public class Outer2 {
    private String a;
    Inner2 inner2 = new Inner2(); // Create inner class instance

    public void modifyState() {
        inner2.changeInstanceVariables(); // Call inner class method
    }
    /*
      Non-static member class
    */ 
    class Inner2 {
         int b;
         void changeInstanceVariables() {
             a = "Updated";
             b = 1234;
             System.out.println("Outer2 variable a = " + a + ". Inner2 variable b = " + b); 
             System.out.println("Outer2 reference = " + Outer2.this + ". Inner2 reference = " + this); 
         }
    }
}

Save and compile the file in directory   c:\_ObjectsAndClasses in the usual way. Lets write a new test class for our Outer2 class.


package info.java8;
/*
  Test Class for Outer2
*/ 
public class Outer2Test {

    public static void main (String[] args) {
        Outer2 outer2 = new Outer2();
        outer2.modifyState();
    }
}

Save, compile and run the file in directory   c:\_ObjectsAndClasses in the usual way.

run outer2 test

The above screenshot shows the output of running our Outer2Test class. We create an inner class as part of the object state of the outer class and then call the modifyState() method to change the state of the outer and inner classes. We also show the syntax for accessing the currently executing object using the this keyword for the outer and inner objects and print this off.

Local Inner Classes Top

Local inner classes can be declared anywhere a local variable can be declared and have the same Method Scope. If you don't require the local inner class to be attached to an instance of the enclosing class, then the nested class should be declared in a static context. Local inner classes cannot contain static members and for readability the coding should be kept to a minimum.

  • The only valid modifers you can apply to a local inner class declaration are final or abstract.
  • Local inner classes can only be instantiated from within the method they are declared in.
  • When instantiating a local inner class, the instantiation code must come after the local inner class declaration.
  • The local inner class can only use final local variables defined within the method it resides in, outside those defined within itself and the outer instance.
  • When creating local inner classes and the code is quite robust, or the code needs to be accessible from more than one method, it is better to make a non-static member class.

Following is an example of a local inner class:


package info.java8;
/*
  A Top-level Class
*/ 
public class Outer3 {
    private String a;
    public void modifyState() {
        /*
          Local inner class
        */ 
        class LocalInner {
            int b;
            void changeInstanceVariables() {
                a = "Updated";
                b = 1234;
                System.out.println("Outer3 variable a = " + a + ". LocalInner variable b = " + b); 
                System.out.println("Outer3 ref. = " + Outer3.this + ". LocalInner ref. = " + this); 
            }
        }
        LocalInner localInner = new LocalInner(); // Create local inner class
        localInner.changeInstanceVariables();
    }
}

Save and compile the file in directory   c:\_ObjectsAndClasses in the usual way. Lets write a new test class for our Outer3 class.


package info.java8;
/*
  Test Class for Outer3
*/ 
public class Outer3Test {

    public static void main (String[] args) {
        Outer3 outer3 = new Outer3();
        outer3.modifyState();
    }
}

Save, compile and run the file in directory   c:\_ObjectsAndClasses in the usual way.

run outer3 test

The above screenshot shows the output of running our Outer3Test class. We create an outer class and then call a method that creates a local inner class instance and calls a method of the local inner class. We also show the syntax for accessing the currently executing object using the this keyword for the outer and inner objects and print this off.

Related Quiz

OO Concepts Quiz 17 - Nested Inner Classes

Lesson 17 Complete

In this lesson we learned about the various ways to code inner classes and local inner classes within our classes.

What's Next?

In the next lesson we learn the various ways to code anonymous inner classes.