geeksforgeeks Java inner class and static nested class




use of static inner class in java (20)

Targeting learner, who are novice to Java and/or Nested Classes

Nested classes can be either:
1. Static Nested classes.
2. Non Static Nested classes. (also known as Inner classes) =>Please remember this


1.Inner classes
Example:

class OuterClass  {
/*  some code here...*/
     class InnerClass  {  }
/*  some code here...*/
}


Inner classes are subsets of nested classes:

  • inner class is a specific type of nested class
  • inner classes are subsets of nested classes
  • You can say that an inner class is also a nested class, but you can NOT say that a nested class is also an inner class.

Specialty of Inner class:

  • instance of an inner class has access to all of the members of the outer class, even those that are marked “private”


2.Static Nested Classes:
Example:

class EnclosingClass {
  static class Nested {
    void someMethod() { System.out.println("hello SO"); }
  }
}

Case 1:Instantiating a static nested class from a non-enclosing class

class NonEnclosingClass {

  public static void main(String[] args) {
    /*instantiate the Nested class that is a static
      member of the EnclosingClass class:
    */

    EnclosingClass.Nested n = new EnclosingClass.Nested(); 
    n.someMethod();  //prints out "hello"
  }
}

Case 2:Instantiating a static nested class from an enclosing class

class EnclosingClass {

  static class Nested {
    void anotherMethod() { System.out.println("hi again"); } 
  }

  public static void main(String[] args) {
    //access enclosed class:

    Nested n = new Nested(); 
    n.anotherMethod();  //prints out "hi again"
  }

}

Specialty of Static classes:

  • Static inner class would only have access to the static members of the outer class, and have no access to non-static members.

Conclusion:
Question: What is the main difference between a inner class and a static nested class in Java?
Answer: just go through specifics of each class mentioned above.

What is the main difference between an inner class and a static nested class in Java? Does design / implementation play a role in choosing one of these?


Nested class: class inside class

Types:

  1. Static nested class
  2. Non-static nested class [Inner class]

Difference:

Non-static nested class [Inner class]

In non-static nested class object of inner class exist within object of outer class. So that data member of outer class is accessible to inner class. So to create object of inner class we must create object of outer class first.

outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass(); 

Static nested class

In static nested class object of inner class don't need object of outer class, because the word "static" indicate no need to create object.

class outerclass A {
    static class nestedclass B {
        static int x = 10;
    }
}

If you want to access x, then write the following inside method

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);

The instance of the inner class is created when instance of the outer class is created. Therefore the members and methods of the inner class have access to the members and methods of the instance (object) of the outer class. When the instance of the outer class goes out of scope, also the inner class instances cease to exist.

The static nested class doesn't have a concrete instance. It's just loaded when it's used for the first time (just like the static methods). It's a completely independent entity, whose methods and variables doesn't have any access to the instances of the outer class.

The static nested classes are not coupled with the outer object, they are faster, and they don't take heap/stack memory, because its not necessary to create instance of such class. Therefore the rule of thumb is to try to define static nested class, with as limited scope as possible (private >= class >= protected >= public), and then convert it to inner class (by removing "static" identifier) and loosen the scope, if it's really necessary.


The Java tutorial says:

Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

In common parlance, the terms "nested" and "inner" are used interchangeably by most programmers, but I'll use the correct term "nested class" which covers both inner and static.

Classes can be nested ad infinitum, e.g. class A can contain class B which contains class C which contains class D, etc. However, more than one level of class nesting is rare, as it is generally bad design.

There are three reasons you might create a nested class:

  • organization: sometimes it seems most sensible to sort a class into the namespace of another class, especially when it won't be used in any other context
  • access: nested classes have special access to the variables/fields of their containing classes (precisely which variables/fields depends on the kind of nested class, whether inner or static).
  • convenience: having to create a new file for every new type is bothersome, again, especially when the type will only be used in one context

There are four kinds of nested class in Java. In brief, they are:

  • static class: declared as a static member of another class
  • inner class: declared as an instance member of another class
  • local inner class: declared inside an instance method of another class
  • anonymous inner class: like a local inner class, but written as an expression which returns a one-off object

Let me elaborate in more details.


Static Classes

Static classes are the easiest kind to understand because they have nothing to do with instances of the containing class.

A static class is a class declared as a static member of another class. Just like other static members, such a class is really just a hanger on that uses the containing class as its namespace, e.g. the class Goat declared as a static member of class Rhino in the package pizza is known by the name pizza.Rhino.Goat.

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

Frankly, static classes are a pretty worthless feature because classes are already divided into namespaces by packages. The only real conceivable reason to create a static class is that such a class has access to its containing class's private static members, but I find this to be a pretty lame justification for the static class feature to exist.


Inner Classes

An inner class is a class declared as a non-static member of another class:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

    private void jerry() {
        Goat g = new Goat();
    }
}

Like with a static class, the inner class is known as qualified by its containing class name, pizza.Rhino.Goat, but inside the containing class, it can be known by its simple name. However, every instance of an inner class is tied to a particular instance of its containing class: above, the Goat created in jerry, is implicitly tied to the Rhino instance this in jerry. Otherwise, we make the associated Rhino instance explicit when we instantiate Goat:

Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();

(Notice you refer to the inner type as just Goat in the weird new syntax: Java infers the containing type from the rhino part. And, yes new rhino.Goat() would have made more sense to me too.)

So what does this gain us? Well, the inner class instance has access to the instance members of the containing class instance. These enclosing instance members are referred to inside the inner class via just their simple names, not via this (this in the inner class refers to the inner class instance, not the associated containing class instance):

public class Rhino {

    private String barry;

    public class Goat {
        public void colin() {
            System.out.println(barry);
        }
    }
}

In the inner class, you can refer to this of the containing class as Rhino.this, and you can use this to refer to its members, e.g. Rhino.this.barry.


Local Inner Classes

A local inner class is a class declared in the body of a method. Such a class is only known within its containing method, so it can only be instantiated and have its members accessed within its containing method. The gain is that a local inner class instance is tied to and can access the final local variables of its containing method. When the instance uses a final local of its containing method, the variable retains the value it held at the time of the instance's creation, even if the variable has gone out of scope (this is effectively Java's crude, limited version of closures).

Because a local inner class is neither the member of a class or package, it is not declared with an access level. (Be clear, however, that its own members have access levels like in a normal class.)

If a local inner class is declared in an instance method, an instantiation of the inner class is tied to the instance held by the containing method's this at the time of the instance's creation, and so the containing class's instance members are accessible like in an instance inner class. A local inner class is instantiated simply via its name, e.g. local inner class Cat is instantiated as new Cat(), not new this.Cat() as you might expect.


Anonymous Inner Classes

An anonymous inner class is a syntactically convenient way of writing a local inner class. Most commonly, a local inner class is instantiated at most just once each time its containing method is run. It would be nice, then, if we could combine the local inner class definition and its single instantiation into one convenient syntax form, and it would also be nice if we didn't have to think up a name for the class (the fewer unhelpful names your code contains, the better). An anonymous inner class allows both these things:

new *ParentClassName*(*constructorArgs*) {*members*}

This is an expression returning a new instance of an unnamed class which extends ParentClassName. You cannot supply your own constructor; rather, one is implicitly supplied which simply calls the super constructor, so the arguments supplied must fit the super constructor. (If the parent contains multiple constructors, the “simplest” one is called, “simplest” as determined by a rather complex set of rules not worth bothering to learn in detail--just pay attention to what NetBeans or Eclipse tell you.)

Alternatively, you can specify an interface to implement:

new *InterfaceName*() {*members*}

Such a declaration creates a new instance of an unnamed class which extends Object and implements InterfaceName. Again, you cannot supply your own constructor; in this case, Java implicitly supplies a no-arg, do-nothing constructor (so there will never be constructor arguments in this case).

Even though you can't give an anonymous inner class a constructor, you can still do any setup you want using an initializer block (a {} block placed outside any method).

Be clear that an anonymous inner class is simply a less flexible way of creating a local inner class with one instance. If you want a local inner class which implements multiple interfaces or which implements interfaces while extending some class other than Object or which specifies its own constructor, you're stuck creating a regular named local inner class.


When we declare static member class inside a class, it is known as top level nested class or a static nested class. It can be demonstrated as below :

class Test{
    private static int x = 1;
        static class A{
        private static int y = 2;
        public static int getZ(){
            return B.z+x;
        }
    }
    static class B{
        private static int z = 3;
        public static int getY(){
            return A.y;
        }
    }
}

class TestDemo{
     public static void main(String[] args){
        Test t = new Test();
        System.out.println(Test.A.getZ());
        System.out.println(Test.B.getY());
    }
}

When we declare non-static member class inside a class it is known as inner class. Inner class can be demonstrated as below :

    class Test{
        private int i = 10;
        class A{
            private int i =20;
            void display(){
            int i = 30;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Test.this.i);
        }
    }
}

I don't think there is much to add here, most of the answers perfectly explain the differences between static nested class and Inner classes. However, consider the following issue when using nested classes vs inner classes. As mention in a couple of answers inner classes can not be instantiated without and instance of their enclosing class which mean that they HOLD a pointer to the instance of their enclosing class which can lead to memory overflow or exception due to the fact the GC will not be able to garbage collect the enclosing classes even if they are not used any more. To make this clear check the following code out:

public class Outer {


    public  class Inner {

    }


    public Inner inner(){
        return new Inner();
    }

    @Override
    protected void finalize() throws Throwable {
    // as you know finalize is called by the garbage collector due to destroying an object instance
        System.out.println("I am destroyed !");
    }
}


public static void main(String arg[]) {

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();

    // out instance is no more used and should be garbage collected !!!
    // However this will not happen as inner instance is still alive i.e used, not null !
    // and outer will be kept in memory until inner is destroyed
    outer = null;

    //
    // inner = null;

    //kick out garbage collector
    System.gc();

}

If you remove the comment on // inner = null; The program will out put "I am destroyed !", but keeping this commented it will not.
The reason is that white inner instance is still referenced GC cannot collect it and because it references (has a pointer to) the outer instance it is not collected too. Having enough of these objects in your project and can run out of memory.
Compared to static inner classes which does not hold a point to inner class instance because it is not instance related but class related. The above program can print "I am destroyed !" if you make Inner class static and instantiated with Outer.Inner i = new Outer.Inner();


Here is key differences and similarities between Java inner class and static nested class.

Hope it helps!

Inner class

  • Can access to outer class both instance and static methods and fields
  • Associated with instance of enclosing class so to instantiate it first needs an instance of outer class (note new keyword place):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Cannot define any static members itself

  • Cannot have Class or Interface declaration

Static nested class

  • Cannot access outer class instance methods or fields

  • Not associated with any instance of enclosing class So to instantiate it:

    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
    

Similarities

  • Both Inner classes can access even private fields and methods of outer class
  • Also the Outer class have access to private fields and methods of inner classes
  • Both classes can have private, protected or public access modifier

Why Use Nested Classes?

According to Oracle documentation there're several reasons (full documentation):

  • It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

  • It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

  • It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.


The difference is that a nested class declaration that is also static can be instantiated outside of the enclosing class.

When you have a nested class declaration that is not static, also known as an inner class, Java won't let you instantiate it except via the enclosing class. The object created out of the inner class is linked to the object created from the outer class, so the inner class can reference the fields of the outer.

But if it's static, then the link does not exist, the outer fields cannot be accessed (except via an ordinary reference like any other object) and you can therefore instantiate the nested class by itself.


The following is an example of static nested class and inner class:

OuterClass.java

public class OuterClass {
     private String someVariable = "Non Static";

     private static String anotherStaticVariable = "Static";  

     OuterClass(){

     }

     //Nested classes are static
     static class StaticNestedClass{
        private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; 

        //can access private variables declared in the outer class
        public static void getPrivateVariableofOuterClass(){
            System.out.println(anotherStaticVariable);
        }
     }

     //non static
     class InnerClass{

         //can access private variables of outer class
         public String getPrivateNonStaticVariableOfOuterClass(){
             return someVariable;
         }
     }

     public static void accessStaticClass(){
         //can access any variable declared inside the Static Nested Class 
         //even if it private
         String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; 
         System.out.println(var);
     }

}

OuterClassTest:

public class OuterClassTest {
    public static void main(String[] args) {

        //access the Static Nested Class
        OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();

        //test the private variable declared inside the static nested class
        OuterClass.accessStaticClass();
        /*
         * Inner Class Test
         * */

        //Declaration

        //first instantiate the outer class
        OuterClass outerClass = new OuterClass();

        //then instantiate the inner class
        OuterClass.InnerClass innerClassExample =  outerClass. new InnerClass();

        //test the non static private variable
        System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); 

    }

}

I don't think the real difference became clear in the above answers.

First to get the terms right:

  • A nested class is a class which is contained in another class at the source code level.
  • It is static if you declare it with the static modifier.
  • A non-static nested class is called inner class. (I stay with non-static nested class.)

Martin's answer is right so far. However, the actual question is: What is the purpose of declaring a nested class static or not?

You use static nested classes if you just want to keep your classes together if they belong topically together or if the nested class is exclusively used in the enclosing class. There is no semantic difference between a static nested class and every other class.

Non-static nested classes are a different beast. Similar to anonymous inner classes, such nested classes are actually closures. That means they capture their surrounding scope and their enclosing instance and make that accessible. Perhaps an example will clarify that. See this stub of a Container:

public class Container {
    public class Item{
        Object data;
        public Container getContainer(){
            return Container.this;
        }
        public Item(Object data) {
            super();
            this.data = data;
        }

    }

    public static Item create(Object data){
        // does not compile since no instance of Container is available
        return new Item(data);
    }
    public Item createSubItem(Object data){
        // compiles, since 'this' Container is available
        return new Item(data);
    }
}

In this case you want to have a reference from a child item to the parent container. Using a non-static nested class, this works without some work. You can access the enclosing instance of Container with the syntax Container.this.

More hardcore explanations following:

If you look at the Java bytecodes the compiler generates for an (non-static) nested class it might become even clearer:

// class version 49.0 (49)
// access flags 33
public class Container$Item {

  // compiled from: Container.java
  // access flags 1
  public INNERCLASS Container$Item Container Item

  // access flags 0
  Object data

  // access flags 4112
  final Container this$0

  // access flags 1
  public getContainer() : Container
   L0
    LINENUMBER 7 L0
    ALOAD 0: this
    GETFIELD Container$Item.this$0 : Container
    ARETURN
   L1
    LOCALVARIABLE this Container$Item L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 1
  public <init>(Container,Object) : void
   L0
    LINENUMBER 12 L0
    ALOAD 0: this
    ALOAD 1
    PUTFIELD Container$Item.this$0 : Container
   L1
    LINENUMBER 10 L1
    ALOAD 0: this
    INVOKESPECIAL Object.<init>() : void
   L2
    LINENUMBER 11 L2
    ALOAD 0: this
    ALOAD 2: data
    PUTFIELD Container$Item.data : Object
    RETURN
   L3
    LOCALVARIABLE this Container$Item L0 L3 0
    LOCALVARIABLE data Object L0 L3 2
    MAXSTACK = 2
    MAXLOCALS = 3
}

As you can see the compiler creates a hidden field Container this$0. This is set in the constructor which has an additional parameter of type Container to specify the enclosing instance. You can't see this parameter in the source but the compiler implicitly generates it for a nested class.

Martin's example

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

would so be compiled to a call of something like (in bytecodes)

new InnerClass(outerObject)

For the sake of completeness:

An anonymous class is a perfect example of a non-static nested class which just has no name associated with it and can't be referenced later.


The terms are used interchangeably. If you want to be really pedantic about it, then you could define "nested class" to refer to a static inner class, one which has no enclosing instance. In code, you might have something like this:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

That's not really a widely accepted definition though.


Inner class and nested static class in Java both are classes declared inside another class, known as top level class in Java. In Java terminology, If you declare a nested class static, it will called nested static class in Java while non static nested class are simply referred as Inner Class.

What is Inner Class in Java?

Any class which is not a top level or declared inside another class is known as nested class and out of those nested classes, class which are declared non static are known as Inner class in Java. there are three kinds of Inner class in Java:

1) Local inner class - is declared inside a code block or method.
2) Anonymous inner class - is a class which doesn't have name to reference and initialized at same place where it gets created.
3) Member inner class - is declared as non static member of outer class.

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in java");
        }
    }
}

What is nested static class in Java?

Nested static class is another class which is declared inside a class as member and made static. Nested static class is also declared as member of outer class and can be make private, public or protected like any other member. One of the main benefit of nested static class over inner class is that instance of nested static class is not attached to any enclosing instance of Outer class. You also don't need any instance of Outer class to create instance of nested static class in Java.

1) It can access static data members of outer class including private.
2) Static nested class cannot access non-static (instance) data member or method.

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in java");
        }
    }
}

Ref: Inner class and nested Static Class in Java with Example


In simple terms we need nested classes primarily because Java does not provide closures.

Nested Classes are classes defined inside the body of another enclosing class. They are of two types - static and non-static.

They are treated as members of the enclosing class, hence you can specify any of the four access specifiers - private, package, protected, public. We don't have this luxury with top-level classes, which can only be declared public or package-private.

Inner classes aka Non-stack classes have access to other members of the top class, even if they are declared private while Static nested classes do not have access to other members of the top class.

public class OuterClass {
    public static class Inner1 {
    }
    public class Inner2 {
    }
}

Inner1 is our static inner class and Inner2 is our inner class which is not static. The key difference between them, you can't create an Inner2 instance without an Outer where as you can create an Inner1 object independently.

When would you use Inner class?

Think of a situation where Class A and Class B are related, Class B needs to access Class A members, and Class B is related only to Class A. Inner classes comes into the picture.

For creating an instance of inner class, you need to create an instance of your outer class.

OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();

or

OuterClass.Inner2 inner = new OuterClass().new Inner2();

When would you use static Inner class?

You would define a static inner class when you know that it does not have any relationship with the instance of the enclosing class/top class. If your inner class doesn't use methods or fields of the outer class, it's just a waste of space, so make it static.

For example, to create an object for the static nested class, use this syntax:

OuterClass.Inner1 nestedObject = new OuterClass.Inner1();

The advantage of a static nested class is that it doesn't need an object of the containing class/top class to work. This can help you to reduce the number of objects your application creates at runtime.


I think that none of the above answers explain to you the real difference between a nested class and a static nested class in term of application design :

OverView

A nested class could be nonstatic or static and in each case is a class defined within another class. A nested class should exist only to serve is enclosing class, if a nested class is useful by other classes (not only the enclosing), should be declared as a top level class.

Difference

Nonstatic Nested class : is implicitly associated with the enclosing instance of the containing class, this means that it is possible to invoke methods and access variables of the enclosing instance. One common use of a nonstatic nested class is to define an Adapter class.

Static Nested Class : can't access enclosing class instance and invoke methods on it, so should be used when the nested class doesn't require access to an instance of the enclosing class . A common use of static nested class is to implement a components of the outer object.

Conclusion

So the main difference between the two from a design standpoint is : nonstatic nested class can access instance of the container class, while static can't.


In the case of creating instance, the instance of non static inner class is created with the reference of object of outer class in which it is defined. This means it have inclosing instance. But the instance of static inner class is created with the reference of Outer class, not with the reference of object of outer class. This means it have not inclosing instance.

For example:

class A
{
  class B
  {
    // static int x; not allowed here…..    
  }
  static class C
  {
    static int x; // allowed here
  }
}

class Test
{
  public static void main(String… str)
  {
    A o=new A();
    A.B obj1 =o.new B();//need of inclosing instance

    A.C obj2 =new A.C();

    // not need of reference of object of outer class….
  }
}

From the Java Tutorial:

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

Static nested classes are accessed using the enclosing class name:

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

see: Java Tutorial - Nested Classes

For completeness note that there is also such a thing as an inner class without an enclosing instance:

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.


First of all There is no such class called Static class.The Static modifier use with inner class (called as Nested Class) says that it is a static member of Outer Class which means we can access it as with other static members and without having any instance of Outer class. (Which is benefit of static originally.)

Difference between using Nested class and regular Inner class is:

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

First We can to instantiate Outerclass then we Can access Inner.

But if Class is Nested then syntax is:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

Which uses the static Syntax as normal implementation of static keyword.


Difference between static and non static nested class in Java

1) Nested static class doesn't need reference of Outer class but non static nested class or Inner class requires Outer class reference. You can not create instance of Inner class without creating instance of Outer class. This is by far most important thing to consider while making a nested class static or non static.

2) static class is actually static member of class and can be used in static context e.g. static method or static block of Outer class.

3) Another difference between static and non static nested class is that you can not access non static members e.g. method and field into nested static class directly. If you do you will get error like "non static member can not be used in static context". While Inner class can access both static and non static member of Outer class.

public class OuterClass {
    private static String message = "Hello JAVA";

    // How to create instance of static and non static nested class
    public static void main(String... args) {

        // creating instance of nested Static class
        InnerClassStatic printer = new InnerClassStatic();

        //calling non static method of nested static class
        printer.printMessage();

        // creating instance of non static nested class or InnerClass class
        // In order to create instance of InnerClass class you need an OuterClass class instance
        OuterClass outerClass = new OuterClass(); //outerClass class instance for creating non static nested class

        InnerClass innerClass = outerClass.new InnerClass();
        innerClass.display();  //calling non static method of InnerClass class

        // we can also combine above steps in one step to create instance of InnerClass class
        InnerClass nonStaticIner = new OuterClass().new InnerClass();

        nonStaticIner.display(); // similarly you can now call InnerClass class method
    }


    // Static nested class
    private static class InnerClassStatic {
        //Only static member of OuterClass class is directly accessible in nested static class

        public void printMessage() {
            // Compile time error if message field is not static
            System.out.println("Message from nested static class : " + message);
        }
    }

    //non static nested class - also called InnerClass class
    private class InnerClass {

        // Both static and non static member of OuterClass class is accessible in this InnerClass class
        public void display() {
            System.out.println(" Message from non static nested or InnerClass class : " + message);
        }
    }
}

Output:

Message from nested static class : Hello JAVA
Message from non static nested or Inner class : Hello JAVA
Message from non static nested or Inner class : Hello JAVA

That's all on Difference between Static and non Static nested class in Java. So far we have only touched member Inner class and not discussed other two types on Inner class e.g. Local class and Anonymous Inner class. In this Java tutorial we have seen What is nested static class in Java and How to create instance of both nested static and non static class in Java.

In summary its easy to create instance of nested static class as it doesn't require instance of Outer class while non static nested class e.g. Inner class will always need an Outer class instance and can not exist without Outer class. If you have to choose between static vs non static class than prefer static nested class if you can use that.


I think, the convention that is generally followed is this:

  • static class within a top level class is a nested class
  • non static class within a top level class is a inner class, which further has two more form:
    • local class - named classes declared inside of a block like a method or constructor body
    • anonymous class - unnamed classes whose instances are created in expressions and statements

However, few other points to remembers are:

  • Top level classes and static nested class are semantically same except that in case of static nested class it can make static reference to private static fields/methods of its Outer [parent] class and vice versa.

  • Inner classes have access to instance variables of the enclosing instance of the Outer [parent] class. However, not all inner classes have enclosing instances, for example inner classes in static contexts, like an anonymous class used in a static initializer block, do not.

  • Anonymous class by default extends the parent class or implements the parent interface and there is no further clause to extend any other class or implement any more interfaces. So,

    • new YourClass(){}; means class [Anonymous] extends YourClass {}
    • new YourInterface(){}; means class [Anonymous] implements YourInterface {}

I feel that the bigger question that remains open which one to use and when? Well that mostly depends on what scenario you are dealing with but reading the reply given by @jrudolph may help you making some decision.


Nested class is a very general term: every class which is not top level is a nested class. An inner class is a non-static nested class. Joseph Darcy wrote a very nice explanation about Nested, Inner, Member, and Top-Level Classes.







inner-classes