2012-10-17 10 views
11

Nel seguente frammento di codice, presumibilmente sembra che dovrebbe emettere qualche errore di compilazione, ma non è così:L'utilizzo di un nome di classe interna e un nome di oggetto stesso 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 
    } 
} 

La classe Outer ha una statica classe al suo interno denominata Inner. Inoltre, dichiara un oggetto (statico) della classe Optional (static Optional Inner = new Optional();)

Questo scopo ed i nomi di classe (all'interno della classe Outer) sono gli stessi che è Inner. Il programma visualizza Optional. L'unica espressione Outer.Inner.obj all'interno di main() è prevista per la visualizzazione di Inner ma non è così. L'uscita effettiva è tuttavia Optional, che è il caso della classe Optional.

Un modo per visualizzare Inner è cambiando il nome dell'oggetto in qualcos'altro.

static Optional Inner1 = new Optional(); 

Dall'output visualizza, risulta che il nome oggetto (o una variabile) viene scelto su un nome di tipo (classe Inner) perché hanno lo stesso nome. Che caso esatto viene applicato qui?

risposta

13

Paragraph 6.4.2 della specifica del linguaggio Java contiene alcune informazioni sulle regole applicabili in questo caso.

Un nome semplice può verificarsi in contesti in cui potrebbe essere interpretato come il nome di una variabile, un tipo o un pacchetto. In queste situazioni, le regole di §6.5 specificano che verrà scelta una variabile in preferenza a un tipo e che verrà scelto un tipo in preferenza per un pacchetto. Pertanto, a volte può essere impossibile fare riferimento a un tipo visibile o dichiarazione di pacchetto tramite il suo nome semplice. Diciamo che tale dichiarazione è oscurata.

Si riferisce al paragrafo 6.5 Determining the Meaning of a Name, che spiega le regole in dettaglio.

Nell'esempio, Outer.Inner potrebbe fare riferimento al tipo della classe nidificata denominata Inner o alla variabile membro statica Inner. Le regole dicono che la variabile sarà scelta rispetto al tipo.

3

In realtà il nome della classe è Esterno $ interno.

Le classi interne sono essenzialmente un hack introdotto in Java 1.1. La JVM in realtà non ha alcun concetto di classe interiore, quindi il compilatore deve schivarlo. Il compilatore genera classeB "al di fuori" di classeA, ma nello stesso package , e poi aggiunge sinteticidi accesso/costruttori ad esso per consentire A per ottenere l'accesso ad essa.

Acquista il seguente post:

Java inner class visibility puzzle

+0

+1 una risposta molto bella! – GingerHead

+0

La cura di Downfer è un commento? – GingerHead

+0

È davvero una bella risposta a una domanda che non è stata posta qui. – LuGo

2

Pensate alla classe interna è in realtà hanno un proprio file .java. Questo ti renderà chiaro perché sceglie la variabile rispetto alla classe Inner.

Problemi correlati