Java Basics – Nested or Inner Class

Inner classes are classes that are declared within another class.

Types of Inner Classes

Inner classes comes in 4 flavors.

  1. Member Inner Class – These classes are declared at member level of the outer class.
  2. Local Inner Class – They are declared within a method of outer class.
  3. Anonymous Class – They are also declared within a method but they don’t have a name.
  4. Static Inner Class – They are static member of the outer class.

Now we know the types of inner classes so now we can focus on describing them in details.

Member Inner Class

These classes are declared within a outer class as a member of the class (just like fields and methods). They fulfill following criteria.

  1.  Member Inner class can be declared private, protected, public or with default access.
  2. They can extend any class and can implement any number of interfaces.
  3. A member inner class can be abstract and final.
  4. A member inner class cannot declare static field or method.
  5. Member inner class has access to all the members of Outer class even the private ones.
  6. Inner class instance is associated with exactly one outer class instance. This association is is created when the inner class is created using new keyword.
  7. You cannot create an inner class without instance of outer class.

Let us look at code snippet to better understand how to declare and use Member inner class.

public class Outer {
    private int x = 10;

    public class Inner{
        private int x = 20;

        public void print(){            
             System.out.println("x : " + x);
             System.out.println("this.x : " + this.x);
             System.out.println("Outer.this.x : " + Outer.this.x);           
        }
    }

    /**
     * invoking inner class from constructor
     */

    public Outer(){
        //notice use of this.new
        Outer.Inner inner = this.new Inner();
        inner.print();
    }

    /**
     * instantiating inner from out side  the enclosing class
     */

    public static void main(String[] args){
        Outer outer = new Outer();
        //notice use of outer.new
        Outer.Inner inner = outer.new Inner();
        inner.print();
    }
}

Output of this code.

x : 20
this.x : 20
Outer.this.x : 10
x : 20
this.x : 20
Outer.this.x : 10

Observations

  1. The inner class in main is instantiated using outer.new operator. This way we associate a inner class with outer class instance.
  2. Inside outer class constructor we used this.new operator. This is a way we instantiate the inner class from within the outer class object.
  3. Use of Outer.this.x – The variable x is common to both inner and outer class. To access the outer x within the inner class you have to use OuterClassName.this.x operator. This syntax is used only within inner class.

Local Inner Class

Local Inner Class are declared within a member method of class. They are instantiated when the method is called and it goes out of scope when method returns. The Local Inner class can be instantiated only within the method. Properties of local inner class are

  1. They do not have access specifier.
  2. They cannot be declared static or have static members.
  3. They cannot access any local variable of the defined in the method unless they are final.
  4. They can access all the members of outer class.

Code Snippet for local Inner Class

public class LocalOuter {
    double radius;
    String property;

    public LocalOuter (double radius,
                       String property){

        this.radius = radius;
        this.property = property;
    }

    public double calculateProperty(){
        class Area{
              public double compute(){
                    return 3.14*radius*radius;
              }
        }

        class Circumference{
                 public double compute(){
                    return 2*3.14*radius;
              }
        }

        if(this.property.equals("area")){
            Area a = new Area();
            return a.compute();
        }else{
            Circumference c = new Circumference();
            return c.compute();
        }
    }

    public static void main(String[] args){
        LocalOuter lo = new LocalOuter(1, "area");
        double area = lo.calculateProperty();
        System.out.println("area : " + area);

        lo = new LocalOuter(1, "circumference");
        double circumference = lo.calculateProperty();
        System.out.println("circumference : " + circumference);
    }
}

You can see the declaration of two local inner class within calculateProperty() method. Notice how they can access the radius and property members of LocalOuter class.

We mentioned in properties of Local Inner Class that they can’t access the local variables of calling method. Why?

We know that JVM does not understand the concept of inner class. Inner Classes are compile time constructs. Whenever compiler encounters a inner class it creates bytecode of a top level class. So in essence it creates two top level class i.e. Outer Class and inner class. Now there is no way by which a object can be aware of local variables of a method of another class. However if the variable is declared final then a copy of it is stored in outer class from where the inner class can get its handle.

Anonymous Class

Anonymous Class is a Local Inner Class that has no name. Anonymous Inner Class is declared and instantiated in one single statement. Anonymous class class has to extend a class or implement interfaces.  Like any other inner classes when a class containing anonymous class is compiled then two top level class is created.

Code Example

public class AnonOuter {
    public boolean flag = true;
    public void doSomething(final int n){

         Thread t = new Thread(){
           public void run(){

               while(flag){
                  int random = (int)(Math.random() * 10) + 1;

                  if(random == n){
                      System.out.println("Password is : " + random);
                      flag = false;
                  }else{
                       System.out.println("bogus try : " + random);
                  }
               }

           }
         };
        t.start();
    }

    public static void main(String[] args){
        AnonOuter ao = new AnonOuter();
        ao.doSomething(9);

    }
}

You can see how we extended the Thread to create a new local thread in method.

Advantages of using Inner classes

So we have seen three flavors of inner classes. Why would be want to the?

  1. Makes code more object oriented – Sometimes a method inside a class becomes too complicated and it makes sense to put the logic inside a class construct. Thus making code more readable and object oriented.
  2. Utility classes – Utility or helper classes which are to be used by only one class can be created as inner class.  For example comparators for an object in collection.
  3. Creating local event handlers.

Static Nested Class

– This is the final type of nested class. They are static classes defined at member level of class.

  1. They don’t have access to members of outer class.
  2. They can be instantiated without an instance of outer class.
  3. Nesting creates a type of namespace. To denote nested class from outside you can suffix name of outside class to name of static nested class.
  4. Access to nested class can be controlled to access specifier. For example making a static nested class private ensures that it cannot be accessed outside the class.
  5. Enclosing class has access to all the fields of static nested class even if they are private.
  6. Static nested class can be imported using  a static import statement.

Code Snippet

public class StaticExample {
    public static class StaticInner{
        public int i = 10;
        public StaticInner(){
        }
        public void doSomething(){
           System.out.println(i);
        }
    }

    public static void main(String[] args){
        StaticExample.StaticInner si = new StaticInner();
        si.doSomething();
    }
}

This is simplest example of static nested class. Just look at main method. StaticInner is referenced using StaticExample.StaticInner, same as any static variable.

So thats all folk. I hope you enjoy this post. Please drop in a comment or two if you feel there is something is amiss.  And also drop in a comment or two if you find the post informative.

Warm Regards

Niraj

Print Friendly, PDF & Email

About Niraj Singh

I am CEO and CoFounder of a startup "Aranin Software Private Limited, Bangalore. I completed my graduation in 2002 as an Aerospace Engineer from IIT Kharagpur. I love working on new ideas and projects and recently released my first open source project JaiomServer "http://jaiomserver.org". I have 9 years of experience in IT industries most of which I have spent in developing community applications for various clients using java. Some of the sites in which I have actively involved with are hgtv.com, food.com, foodnetwork.com, pickle.com, diynetwork.com etc.
This entry was posted in Core Java, Uncategorized and tagged . Bookmark the permalink.