2012-10-17 5 views
11

Im folgenden Codeausschnitt verwenden, vermutlich scheint es, dass es einige Übersetzungsfehler ausgeben sollte, aber es funktioniert nicht:einen inneren Klassennamen und einen Objektnamen gleiche in Java

class Outer { 
    public static class Inner { 
     static String obj = "Inner"; 
    } 

    static Optional Inner = new Optional(); 
    //The (inner) class name and the object name are same. 
} 

class Optional { 
    String obj = "Optional"; 
} 

public class Main { 

    public static void main(String[] args) { 
     System.out.println(Outer.Inner.obj); 
     //Refers to the string inside the optional class 
    } 
} 

Die Klasse Outer ein statisches hat Klasse darin nannte Inner. Außerdem erklärt es ein Objekt (statisch) der Klasse Optional (static Optional Inner = new Optional();)

Diese Aufgabe und die Klassennamen (in der Klasse Outer) sind die gleichen, die Inner ist. Das Programm zeigt Optional an. Der einzige Ausdruck Outer.Inner.obj innerhalb von main() wird erwartet, Inner anzuzeigen, tut es aber nicht. Der tatsächliche Ausgang ist jedoch Optional, was der Fall der Optional Klasse ist.

Eine Möglichkeit, Inner anzuzeigen, besteht darin, den Objektnamen in einen anderen Namen zu ändern.

static Optional Inner1 = new Optional(); 

Vom Ausgang es zeigt, scheint es, dass die Objektnamen (oder eine Variable) über einen Typnamen gewählt (die Klasse Inner), weil sie den gleichen Namen haben. Welcher genaue Fall wird hier angewendet?

Antwort

13

Paragraph 6.4.2 der Java-Sprachspezifikation enthält einige Informationen über die Regeln, die in diesem Fall gelten.

Ein einfacher Name kann in Kontexten auftreten, in denen er möglicherweise als Name einer Variablen, eines Typs oder eines Pakets interpretiert werden kann. In diesen Situationen geben die Regeln von §6.5 vor, dass eine Variable anstelle eines Typs gewählt wird und dass ein Typ einem Paket vorgezogen wird. Daher kann es manchmal unmöglich sein, auf einen sichtbaren Typ oder eine Paketdeklaration über seinen einfachen Namen zu verweisen. Wir sagen, dass eine solche Erklärung ist obscured.

Dies bezieht sich auf den Absatz 6.5 Determining the Meaning of a Name, der die Regeln im Detail erklärt.

In Ihrem Beispiel könnte sich Outer.Inner auf den Typ der geschachtelten Klasse mit dem Namen Inner oder die statische Elementvariable Inner beziehen. Die Regeln sagen, dass die Variable über den Typ ausgewählt wird.

3

Eigentlich ist der Klassenname Outer $ Inner.

Inner Klassen sind im Wesentlichen ein Hack in Java 1.1 eingeführt. Die JVM hat eigentlich kein Konzept einer inneren Klasse, und so muss der Compiler sie umgehen. Der Compiler erzeugt KlasseB „außerhalb“ von KlasseA, aber in dem gleichen Paket, und fügt dann synthetischAccessoren/Konstrukteurs es A zu ermöglichen, Zugang zu ihm zu bekommen.

Kasse folgender Beitrag:

Java inner class visibility puzzle

+0

+1 eine sehr nette Antwort! – GingerHead

+0

Downvoter Pflege Kommentar? – GingerHead

+0

Es ist in der Tat eine sehr nette Antwort auf eine Frage, die hier nicht gestellt wurde. – LuGo

2

Denken Sie an der inneren Klasse hat ihre eigene .java-Datei tatsächlich hat. Das wird Ihnen klar machen, warum es die Variable über die innere Klasse wählt.