关于java:静态和非静态内部类的区别?

The difference of static and non-static inner classes?

我正在阅读有效的Java 2 -项目22,它在标题中写道:

"Favor static member classes over non-static"

但是在这一章的结尾

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

1
2
3
4
5
6
7
8
9
10
11
12
// 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> {
        ...
    }
}

我做了一个测试程序,看看它们之间是否有任何区别,这里就是。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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");
        }
    }
}

输出是

I am inner
I am inner

所以,他们做了同样的工作。

我想知道为什么在这个例子中使用非静态类?


迭代器通常需要首先引用用于创建它的集合。可以使用一个显式提供了对集合的引用的静态嵌套类来实现这一点,也可以只使用一个隐式引用的内部类。

基本上,如果嵌套类的每个实例都需要一个封闭类的实例来操作(而该实例不变),那么您也可以将其设置为一个内部类。否则,将其设置为静态嵌套类。


区别在于,非静态内部类对包含类具有隐式引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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()
    }
  }
}


static与非静态嵌套类的区别在于,非静态嵌套类隐式地与外部类的一个实例相关联,它们可以称为OuterClassName.this。此引用在实现迭代器时很有用,因为它们需要访问与其相关的集合的成员。您可以通过使用static嵌套类来实现相同的事情,该类显式地将引用传递给外部类。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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….
}
}

没有静态内部类,它是静态嵌套类。"非静态[嵌套]类的每个实例都隐式地与其包含类的封闭实例关联…可以在封闭实例上调用方法。"

静态嵌套类无权访问封闭实例。

参考文献:这条索线