2014-01-14 9 views
5

Im folgenden Beispiel die import ist notwendig, andernfalls wird die Java-Compiler beschweren sich, dass Nested kann nicht auf einen Typ in Iterable<Nested> gelöst werden:Warum muss ich eine geschachtelte Klasse in die definierte Klasse importieren?

package test; 

import test.Example.Nested; 

public class Example implements Iterable<Nested> { 

    public final static class Nested {} 

} 

(mit Iterable<Example.Nested> anstelle eines Import funktioniert auch)

Diese tritt nur auf, wenn eine verschachtelte Klasse in der Definition der äußeren Klasse referenziert wird, z wenn es als parametrischer Typ verwendet wird, aber auch wenn es erweitert/implementiert wird (was zu einem anderen Fehler führt, sobald der Compiler die Klasse auflösen kann), oder wenn es als oder in einer Annotation verwendet wird.

Meine Frage ist: Warum kann der Compiler die geschachtelte Klasse nicht finden, ohne eine explizite Deklaration?

Antwort

5

Eine Erklärung ist sichtbar in den Rahmen kommt es in und für die Mitglieder, dass Umfang ist der Stoff zwischen den umschließenden geschweiften Klammern oder als spec es ausdrückt:

Der Umfang einer Erklärung eines Mitglied m in einer Klasse deklariert oder vererbt C (§8.1.6) ist der gesamte Körper von C, einschließlich aller geschachtelten Typdeklarationen.

Warum ist es so definiert ist etwas, das nur die Schöpfer von Java mit hinreichender Sicherheit beantworten können, aber ich vermute, dass sie so einfach eine Regel wie möglich wollten, und zu sagen, dass alle Mitglieder, Variablen und so weiter Innerhalb der umgebenden geschweiften Klammern sind eine sehr einfache Regel sichtbar.

Und übrigens: Sie müssen den Typ nicht importieren, Sie können stattdessen einen qualifizierten Namen verwenden. In Ihrem Beispiel würde gelesen, dass:

public class Example implements Iterable<Example.Nested> { } 
1

Verschachtelte Klassen werden als <OuterClass>.<InnerClass> Bezug genommen wird, so Iterable<Example.Nested> wäre der typische Weg, dies in Java zu tun, obwohl import verwendet, ist auch eine Option.

Siehe Nested Classes im Java-Lernprogramm.

+0

denke ich, OP Problem mit der Tatsache, dass die äußere Klasse in der Lage sein sollte, auf ihre geschachtelte Klasse ohne das Präfix "Äußeres" zuzugreifen. Zum Beispiel können Sie das 'Nested'-Feld innerhalb der' Example'-Klasse deklarieren, ohne die 'Example.Nested'-Typ-Deklaration verwenden zu müssen, aber Sie können sie nicht in 'Iterable ' verwenden. – Pshemo

+1

@AmirPashazadeh: Nun, OP * muss * die Importklausel nicht verwenden; nach der Outer.Inner-Konvention wird funktionieren, und ist der typische Weg.Aber wenn er eine Antwort "Warum" möchte, ist das Beste, was ich geben kann, "So funktioniert Java". – Jimothy

+0

@AmirPashazadeh: Wenn Ihr Einspruch der Link "Nested Classes" ist, habe ich ihn angegeben, weil er ua erläutert, wie auf verschachtelte Klassen (Outer.Inner) verwiesen wird. – Jimothy

1

Der folgende Code ist noch nicht „innerhalb“ der Klasse Körper

public class Example implements Iterable<Nested> 
{ 
    // class body starts here 

Nested außerhalb der Klasse verwiesen wird und so müssen Sie entweder import oder verwenden Example.Nested im Bereich verschachtelt sein.

, wenn Sie einen ähnlichen Code in der Klasse Körper gelegt wird es funktionieren:

{ 
     // class body starts here 

     public void foo(Iterable<Nested> x) ... 
} 

Dies funktioniert gut, weil Sie jetzt im Klassenbereich, wo verschachtelt ist definiert und verfügbar unqualifizierte

Verwandte Themen