Skip to content

Instantly share code, notes, and snippets.

@esfand
Last active May 2, 2022 11:14
Show Gist options
  • Save esfand/7180794 to your computer and use it in GitHub Desktop.
Save esfand/7180794 to your computer and use it in GitHub Desktop.
Difference between static and non-static java inner class in Java

Difference between static and non-static java inner class.

A static java inner class cannot have instances. A non-static java inner class can have instances that belong to the outer class.


james vinett said on 16/11/2009,

“A static java inner class cannot have instances.”

I’ve seen this written before, but it cannot be true. You can, in fact, call “new” on a static nested class and therefore have an instance. My understanding of a static nested class is that it has exactly the same behavior as an outer class. Nesting in this case is a design choice.

Would you, please, explain to me, if I am incorrect, what it is exactly that you mean by your statement. Thanks.


Prasanna said on 16/12/2009, Please go for this link for more differences and detailed explanation

http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html


ashish said on 07/05/2010,

A static inner class can have instances but they dont have enclosing instances! which a non-static inner class have.

eg.

class A{
    static class B{} // static-member class
    class C{} // non-static member class
}

class D{
    public static void main(String st[]){
        A obj1 = new A();
        A.C = obj1.new C();//obj1 is enclosing instance
        A.B = new A.B(); //No enclosing instance requird
    }
}

W. R. Shastry said on 29/11/2010,

There are two defference between static inner and non static inner class.

  1. In the case of declaring data memeber and member method, non static inner class cannot have static data member and static member method. But Static Inner class can have static and non static data member and member method.

  2. In the case of creating instance, the instance of non sstatic 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….
}

}


--------------------

RaMesh said on 08/09/2011,
The functionality of static and non static inner classes are like static and nonstatic instance variables in a class.

---------------------

Kishore said on 19/12/2011,

In Inner Classes we have 4 types
1.  Normal Regular Inner classes
2.  Method Local Inner Classes
3.  Ananmuos Inner Classes
4. Static Nested Inner Classes

1) Normal Regular Inner classes:    
a) These classes will not have the static members in it    
b) if we want to access this class we have to access through the Outer class only i.e, only Outer class members 
   will access this class    
c) we cant Execute inner class directly from the Command Prompt because it doesnt contain the main method    

eg:

public class Outer{ class Inner { public void m1(){ System.out.println(“—–Inner—-”); } }

public static void main(String[] a){

Outer o = new Outer(); // we can access the inner class just liek the other member variables Outer.Inner oi = o.new Inner(); // Outer.Inner oi = new Outer().new Inner(); oi.m1();

}

public void method(){ System.out.println(“—–normal method—-”);

}

}


Run:

java Outer
java Outer$Inner (here inner class class file name will be like “OuterClassName$InnerClassName.class”)


2) Method Local Inner Classes;
a) Innerclasses declared inside a method body : it can access the outer class members but it cant acesss the local variables declared in the method
b) Inner Classes declared as a Method Parameter

3) Ananmuos Innerclasses :
a) a inner classe with out a name
eg : Runnable r = new Runnable(){
public void run(){
System.out.println(“– Inner Class Run Method”);
}

};
4) Static Nested Inner Class:
a) This is same as the Normal regular Innerclass, but it has the static members available
b) static members are available so we can run directly the InnerClass
c) if we want to create the Inner Class Object no need to depend on the Outer Class Object

public class Outer{
static class Inner	{

public void m1(){
System.out.println(“—–Inner—-”);
}

public static void main(String[] a){
System.out.println(“—–Inner class Main method —-”);
}

}

public static void main(String[] a){

// we can access the inner class just liek the other member variables
Outer.Inner oi = new Outer.Inner();
oi.m1();

}

public void method(){
System.out.println(“—–normal method—-”);

}

}

Run:
> java Outer
> java Outer$Inner (here inner class class file name will be like “OuterClassName$InnerClassName.class”)

D:\Practices\Java\Test>java Outer$Inner
—–Inner class Main method —-

D:\Practices\Java\Test>java Outer
—–Inner—-

Please correct me if i am wrong. i will give update on the remaining two inner classes dependiing on the comments for this.


------------------

Djhseen said on 28/11/2012,

As i know, static methods can be called in the main class without necessity of making an object of the class that 
contains that method.

for example u have

class X { //here’s the class int some_method (int a) //here’s the method {some operations}}

class some{public static void main(String[] args){ int a; //here’s some integer

X.some_method(a) ; /* we used method (some_method) from the calss a without the necessity of making an object from that class */ }}


Anonymous
said on 30/12/2012,

class X { //here’s the class Static int some_method (int a) //here’s the method {some operations}}

class some{public static void main(String[] args){ int a; //here’s some integer

X.some_method(a) ; /* we used method (some_method) from the calss a without the necessity of making an object from that class */ }}


if u put static just before the some_method then u can do like this else u will get an error.

--------------

sathiyaraj said on 29/11/2012,

Actually i wrote a program in java language, i used ImageIO static method to write the image but my input value is not a static so no error show even result also not showing.

Reply
tamilsevi said on 18/12/2012,
how to access a non static method in static inner class….?…

-----------------


Anonymous said on 30/12/2012,

Inside static inner class,create an object of enclosing class(outer class)which has non static method and use 
this object to call non static method.

public class learnStatic {

public void getValue1(){ int b=12; System.out.println(“Inside getValue1 : b :” + b);

} static class Inner{ static void getValue2(){ getInner(); } static void getInner(){

learnStatic obj = new learnStatic(); System.out.println(“Here we calling non static method inside static inner class”); obj.getValue1(); } }

}

public class callStatic {

/**

  • @param args */ public static void main(String[] args) { // TODO Auto-generated method stub learnStatic objStatic = new learnStatic(); objStatic.getValue1(); learnStatic.Inner.getValue2();

}

}


correct me if I am wrong.

--------------

Nested Classes

The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated here:

class OuterClass {
    ...
    class NestedClass {
        ...
    }
}

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

class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class. As a member of the OuterClass, a nested class can be declared private, public, protected, or package private. (Recall that outer classes can only be declared public or package private.)

Why Use Nested Classes?

Compelling reasons for using nested classes include the following:

  • 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.

Static Nested Classes

As with class methods and variables, a static nested class is associated with its outer class. And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class: it can use them only through an object reference.

Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience. 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();

Inner Classes

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.

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();

There are two special kinds of inner classes: local classes and anonymous classes.

Shadowing

If a declaration of a type (such as a member variable or a parameter name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. You cannot refer to a shadowed declaration by its name alone. The following example, ShadowTest, demonstrates this:

 
public class ShadowTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);
            System.out.println("this.x = " + this.x);
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}

The following is the output of this example:

x = 23
this.x = 1
ShadowTest.this.x = 0

This example defines three variables named x: the member variable of the class ShadowTest, the member variable of the inner class FirstLevel, and the parameter in the method methodInFirstLevel. The variable x defined as a parameter of the method methodInFirstLevel shadows the variable of the inner class FirstLevel. Consequently, when you use the variable x in the method methodInFirstLevel, it refers to the method parameter. To refer to the member variable of the inner class FirstLevel, use the keyword this to represent the enclosing scope:

System.out.println("this.x = " + this.x);

Refer to member variables that enclose larger scopes by the class name to which they belong. For example, the following statement accesses the member variable of the class ShadowTest from the method methodInFirstLevel:

System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);

Static inner classes

Use static inner classes to add supplementary capabilities to your code

With this tip, you can add the use of static inner classes to your bag of Java tricks. A static inner class is a class that is defined inside of a different class's definition and marked as being static. I'll show you an example of using static inner classes to add testing code to a class.

Static inner classes are pretty simple in concept and implementation. Basically, you define a static class inside your primary class:

public class Foo
    {
    // ....
    public static class Test
      {
      public static void main (String[] args)
          {
          // ....
          }
      }
    }

In terms of adding supplementary code to your primary class, the key point is that a static inner class is compiled into a completely separate .class file from the outer class. For example, if the outer class is named Foo, then an inner class of Foo, which is named Test, would be compiled into Foo$Test.class. The separation of .class files means that you can keep the supplemental, nested code tightly coupled to the primary, outer class. They are in the same source file, and the inner class is actually inside the outer class. All that and you don't have to pay any sort of deployment or runtime cost. Score! For example, if the supplemental code is only used for, say, debugging, then you only have to ship the Foo.class file and leave the Foo$Test.class file at home.

I primarily use that trick for writing example code to show how to use the primary outer class, for writing down and dirty debugging code, and for writing unit tests to automate the validation of the class's behavior. (Of course, being a diligent developer, I tend to transform the debugging code into unit tests.)

Note that to execute the main() method of that Foo.Test class, you use:

  % java Foo$Test

If you're using a command shell that uses "$" as a metacharacter, you would instead use:

  % java Foo\$Test

Another interesting point to note is that static inner classes have, by definition, access to the outer class's protected and private fields. That is both a blessing and a curse since you can, in essence, violate the encapsulation of the outer class by mucking up the outer class's protected and private fields. Tread with care! The only proper use of that capability is to write white-box tests of the class -- since I can induce cases that might be very hard to induce via normal black-box tests (which don't have access to the internal state of the object).

The XYPair class is quite simple. It just provides for an immutable pair of integers, (x, y). The XYPair.Test class has a main() method that drives a simple test of the XYPair and prints the results. Play with both the testing and core code to experiment with various problems.

If you're more bold, you might want to check out the JUnit Java unit testing framework. You can uncomment out the various spots indicated in the source code and then run the tests via JUnit's test engine.

Conclusion By using static inner classes, you can add additional support functionality to your systems for capabilities such as testing, while incurring no penalties in normal, production deployment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment