Salih Erikci
Salih Erikci

Reputation: 5087

The difference of static and non-static inner classes?

I was reading Effective Java 2 - Item 22 and it says in the title:

"Favor static member classes over non-static"

but at the end of the chapter

Implementations of the collection interfaces, such as Set and List, typically use nonstatic member classes to implement their iterators:

// Typical use of a nonstatic member class
public class MySet<E> extends AbstractSet<E> {
    ... // Bulk of the class omitted

    public Iterator<E> iterator() {
        return new MyIterator();
    }

    private class MyIterator implements Iterator<E> {
        ...
    }
}

I made a test program to see if there is any difference between them and here it is.

public class JavaApplication7 {


    public static void main(String[] args) {
        // TODO code application logic here
        JavaApplication7 t = new JavaApplication7();

        Inner nonStaticObject = t.getAClass();
        Sinner staticObject = new JavaApplication7.Sinner();

        nonStaticObject.testIt();
        staticObject.testIt();         
    }

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

    static class Sinner{
        public void testIt(){
            System.out.println("I am inner");
        }
    }

    class Inner{
        public void testIt(){
            System.out.println("I am inner");
        }
    }
}

The output is

I am inner I am inner

So, they did the same job.

I wonder Why non-static class is used in this example?

Upvotes: 2

Views: 2462

Answers (5)

Ankit Jain
Ankit Jain

Reputation: 2270

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

Upvotes: 0

stinepike
stinepike

Reputation: 54732

there is no such thing as a static inner class, It is static nested class. "Each instance of a nonstatic [nested] class is implicitly associated with an enclosing instance of its containing class... It is possible to invoke methods on the enclosing instance."

A static nested class does not have access to the enclosing instance.

reference: this so thread

Upvotes: 0

Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31283

the difference is that non-static inner class have an implicit reference to the containing class.

public class JavaApplication7 {

  //You can access this attribute in non-static inner class
  private String anyAttribute;

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

  static class Sinner{
    public void testIt(){
      //Here, you cannot access JavaApplication7.this
    }
  }

  class Inner{
    public void testIt(){
        //Here, you can access JavaApplication7.this
        //You can also access *anyAttribute* or call non-static method getAClass()
    }
  }
}

Upvotes: 3

Joni
Joni

Reputation: 111389

The difference between static and non-static nested classes is that the non-static ones are implicitly associated with an instance of the outer class, which they can refer to as OuterClassName.this. This reference is useful when implementing iterators, as they need access to the members of the collection they are related to. You could achieve the same thing by using a static nested class which is explicitly handed a reference to the outer class.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1503459

An iterator usually needs to refer to the collection used to create it in the first place. You can do that with a static nested class which is explicitly provided with a reference to the collection - or you can just use an inner class, which has that reference implicitly.

Basically, if every instance of the nested class needs an instance of the enclosing class to operate (and that instance doesn't change), then you might as well make it an inner class. Otherwise, make it a static nested class.

Upvotes: 4

Related Questions