2013-07-26 8 views
9

Wie können die statische innere Klasse M und das statische Element M [der Klasse C] den gleichen Namen haben?Statische innere Klasse und statisches Element einer Klasse teilen sich NAME?

Der folgende Code erzeugt „White“ als Ausgabe:

public class Amazed{ 

    public static void main(String[] args) { 
     System.out.println(B.M.W); 
    } 
} 

class B { 
    public static class M {  
     static String W = "Black"; 
    } 

    static C M = new C(); 
} 

class C { 
    String W = "White"; 
} 

wie das Element Objekt zugegriffen wird, und nicht die statische Klasse Mitglied: W [ „Black“]

, wenn ich die zugreifen möchten Mitglied innerhalb der statischen Klasse M wie geht das?

+1

Ich mag die Methode "Meth" nimmt Sie nirgends. Eine sehr lange while-Schleife könnte jedoch besser geeignet sein. – thatidiotguy

+0

@thatiidiotguy: Oder etwas, das rekursiert, bis es den Stapel bläst. –

+0

Danke BMT. Aber ich verstehe die Spezifikation der Verdunkelung und Neuklassifizierung nicht ... könnte mir jemand dabei helfen. – Dineshkumar

Antwort

2

Chapter 6 of the Java Language Specification (besonders Section 6.5) buchstabiert die grausigen Einzelheiten, wie Java aussondert, was eine bestimmte Kennung in einem bestimmten Kontext bedeutet. Die Regeln sind ziemlich komplex, aber grob gesagt Java sechs Namensräume hat:

  • Paketnamen
  • Typnamen
  • Feld (variable) Namen
  • Methodennamen
  • lokale Variablennamen (einschließlich Parameter)
  • Etiketten

Die gleiche Kennung kann u sein, sed für Entitäten in jedem dieser Namensräume. Beachten Sie, dass Typ- (Klassen-) Namen und Feldnamen getrennt voneinander existieren. Dies erklärt, warum Ihr Code legal ist.

Vererbte Namen im selben Namensraum können manchmal auch schattiert oder maskiert werden. Manchmal ist eine Kennung nicht eindeutig. es muss dann in irgendeiner Weise qualifiziert werden (z.B., mit einem Paketnamen) oder der Compiler wird sich beschweren.

-Code obfuscators verwenden, um dies zu großem Vorteile, bis zu dem Punkt, wo Sie mit einem Paket a.a und einer Klasse mit dem Namen a in Paket mit dem Namen können am Ende a (die als a.a identifiziert würden auch). Java-Schlüsselwörter wie do und for sind legale Namen in .class-Dateien (aber nicht in der Java-Quelle). Es hilft, Reverse Engineering zu einem echten Bären zu machen.

0

In Ihrem speziellen Fall, in dem M instanziiert werden können Sie die Tatsache, dass die Statik in einer nicht-statische Art und Weise zugegriffen werden kann, verwenden könnte:

public class Amazed{ 
    @SuppressWarnings("static-access") 
    public static void main(String[] args) { 
     B.M val = new B.M(); 
     System.out.println(val.W); 
    } 
} 

class B { 
    public static class M {  
     static String W = "Black"; 
    } 

    static C M = new C(); 
} 

class C { 
    String W = "White"; 
} 

Die oben gedruckt wird ‚Black‘, weil Sie die Kennung eindeutig gemacht durch Bezug auf es durch eine Instanz von B.M. Dies ist natürlich keine gute Idee im Produktionscode, da auf statische Felder nicht auf nicht statische Weise zugegriffen werden sollte. Ebenso müssen Sie eine Instanz von B.M erstellen.

1

Die Variable verdeckt den gleichnamigen Typ. Wenn ein Name entweder als Variable oder als Typ interpretiert werden kann, wird die Variable bevorzugt.

Sie können dies vermeiden, indem Sie ihnen nicht den gleichen Namen geben.

Aus der Java Language Specification, section 6.4.2: Obscuring:

6.4.2. Obscuring

Ein einfacher Name kann in Kontexten auftreten, in denen möglicherweise als der Name einer Variablen, eines Typs oder eines Pakets interpretiert werden kann. In diesen Situationen geben die Regeln von § 6.5 vor, dass eine Variable einem Typ vorgezogen wird und dass ein Typ bevorzugt vor einem Paket ausgewählt 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 verdeckt ist.

+0

wie es gewählt wird? Was ist die Reihenfolge der Präferenz? – Dineshkumar

+1

1) Variable 2) Typ 3) Paketname –

+0

bedeutet Art hier etwas anderes als Klasse? – Dineshkumar

0

Nach jeder Hilfe und wenig Spiel habe ich festgestellt, dass wir auch ohne das Erstellen eines Objekts für die innere Klasse auf das Mitglied W "Black" zugreifen können.

einfach mit dieser Anweisung

M.W 

Aber ich kann Zugriffsebene nicht herausfinden. [weil seine Öffentlichkeit?] sogar ohne Öffentlichkeit funktionierte es. wie ist das?