2013-07-07 1 views
2

Я читал Эффективное Java 2 - пункт 22, и он говорит, что в названии:Разница статических и нестатических внутренних классов?

«Фавор статических классов членов над нестатическим»

но в конце главы

Реализации интерфейсов сбора данных, таких как Set и List, , как правило, используют нестатические классы-члены для реализации своих итераторов:

// 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> { 
     ... 
    } 
} 

Я сделал тестовую программу, чтобы узнать, есть ли разница между ними, и вот она.

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"); 
     } 
    } 
} 

Выход

Я внутренний Я внутренний

Таким образом, они сделали ту же работу.

Интересно, почему в этом примере используется нестатический класс?

ответ

4

Итератору обычно необходимо обратиться к коллекции, используемой для ее создания. Вы можете сделать это со статическим вложенным классом, который явно снабжен ссылкой на коллекцию, или вы можете просто использовать внутренний класс, который имеет эту ссылку неявно.

В принципе, если каждый экземпляр вложенного класса нуждается в экземпляре охватывающего класса для работы (и этот экземпляр не изменяется), вы также можете сделать его внутренним классом. В противном случае сделайте его статическим вложенным классом.

2

Разница между static и нестатическими вложенными классами заключается в том, что нестатические неявно связаны с экземпляром внешнего класса, который они могут назвать OuterClassName.this. Эта ссылка является полезной при реализации итераторов, поскольку они нуждаются в доступе к членам коллекции, к которым они относятся. Вы можете добиться того же, используя класс static, который явно передал ссылку на внешний класс.

3

Разница заключается в том, что нестатический внутренний класс имеет неявную ссылку на содержащий класс класс .

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() 
    } 
    } 
} 
0

нет такого понятия, как статический внутренний класс, Это статический вложенный класс. «Каждый экземпляр нестатического [вложенного] класса неявно связан с вмещающим экземпляром его содержащего класса ... Можно вызвать методы для экземпляра-оболочки».

Статический вложенный класс не имеет доступа к прилагаемому экземпляру.

ссылка: this so thread

0
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…. 
} 
}