2011-08-21 2 views

risposta

75

di accedere alle classi interne con $

java.nio.channels.FileChannel$MapMode/READ_ONLY 
+27

Non dimenticare che se stai importando FileChannel con la funzione 'import' o con la parola chiave': import', devi anche specificare che stai importando 'FileChannel $ MapMode' –

+1

Grazie @TerjeDahl. Penso che dovresti modificare la tua domanda per includerla, Hamza Yerlikaya. – Joe

11

La sintassi (FileChannel/MapMode) è una semplificazione e destinato solo per i campi e metodi statici (per i campi, si può anche omettere le parentesi)! Anche i moduli . e .. sono per campi/metodi ma NON per classi nidificate/interne!

Per JVM, una classe interna Outer.Inner è solo una classe denominata Outer$Inner (e il compilatore crea un file Outer$Inner.class per questo). Il compilatore Java ti consente di fare riferimento ad esso tramite Outer.Inner. È inoltre possibile definire una classe non interna denominata Outer$Inner a cui il compilatore consente di fare riferimento come Outer$Inner. Non è possibile definire entrambi allo stesso tempo, però, dal momento che entrambi avrebbero i nomi delle classi di Outer$Inner (e .class file denominati Outer$Inner.class, quindi questo sarebbe un nome di classe duplicato!)

Quando si utilizza la riflessione - per esempio con Class.forName() - (in genere per introdurre un po 'di dinamicità) non è possibile omettere il nome del pacchetto di una classe importata ed è necessario utilizzare il nome della classe reale con il segno $ invece di un punto.

Probabilmente per la sua natura dinamica, Clojure ha lo stesso approccio, quindi è necessario utilizzare il modulo my.package.Outer$Inner se la classe è in my.package - anche se hai già importato la classe esterna! Per evitare il nome del pacchetto, è possibile importare in modo esplicito la classe interna my.package.Outer$Inner e quindi fare riferimento ad esso come Outer$Inner (il suo nome di classe reale!), Ma non sarà ridurre questo a Inner semplicemente importandolo:

Inner non ha significato per la JVM, solo il Java-Compiler ti offre questa scorciatoia dal contesto della compilazione (che NON è disponibile per JVM e metodi come Class.forName in fase di esecuzione!) ... OK, in Clojure puoi, naturalmente, definire sempre: (def Inner Outer$Inner) ... o (def Tom Outer$Inner) o (def Harry Outer$Inner) o qualsiasi altra cosa ... se ti piace di più.

+0

questa è forse una bella spiegazione. grazie. – tutysara