statische innere Klasse und statisches Mitglied einer Klasse teilt sich NAME? [Duplikat]

9

Wie kann die statische innere Klasse M und das statische Element M [der Klasse C ] den gleichen Namen haben?

Der folgende Code generiert "Weiß" als Ausgabe:

%Vor%

Wie auf das Elementobjekt zugegriffen wird und nicht auf das statische Klassenmitglied: W ["Black"]

Wenn ich auf das Mitglied innerhalb der statischen Klasse M zugreifen möchte, wie geht das?

    
Dineshkumar 26.07.2013, 17:08
quelle

4 Antworten

2

Kapitel 6 der Java-Sprachspezifikation (insbesondere Abschnitt 6.5 ) beschreibt die grausigen Details wie Java sortiert aus, was ein bestimmter Bezeichner in einem bestimmten Kontext bedeutet. Die Regeln sind ziemlich komplex, aber grob gesagt hat Java sechs Namensräume:

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

Dieselbe Kennung kann für Entitäten in jedem dieser Namensräume verwendet werden. 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 sein. Manchmal ist eine Kennung nicht eindeutig. es muss dann in irgendeiner Weise (z. B. mit einem Paketnamen) qualifiziert werden oder der Compiler wird sich beschweren.

Code-Obfuscatoren nutzen dies zu einem großen Vorteil, bis zu einem Paket namens a.a und einer Klasse namens a im Paket a (das auch als a.a identifiziert werden würde). Ganz zu schweigen davon, dass Java-Schlüsselwörter wie do und for legale Namen in .class-Dateien sind (aber nicht in der Java-Quelle). Es hilft, Reverse Engineering zu einem echten Bären zu machen.

    
Ted Hopp 26.07.2013, 17:32
quelle
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-Sprachspezifikation Abschnitt 6.4. 2: Verschleierung :

  

6.4.2. Verschleierung

     

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

    
Andy Thomas 26.07.2013 17:29
quelle
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 Aussage

%Vor%

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

    
Dineshkumar 26.07.2013 17:42
quelle
0

In Ihrem speziellen Fall, in dem M instanziiert werden kann, könnten Sie die Tatsache verwenden, dass auf statische Methoden nicht-statisch zugegriffen werden kann:

%Vor%

Der obige Ausdruck druckt "Schwarz", weil Sie den Identifikator durch eine Instanz von B.M eindeutig identifiziert haben. 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.

    
cyon 26.07.2013 17:27
quelle