2011-08-21 10 views
49

は基本的に私は何をする必要があるか、私は明白Clojure interop経由で静的内部Javaクラスにアクセスするには?

(.. FileChannel MapMode READ_ONLY) 

をやってみました。この

FileChannel.MapMode.READ_ONLY 

であるが、それはのためのように指定しても/表記例外

java.lang.NoSuchFieldException: MapMode 

を投げ終わりますinterop documentationの静的フィールドにアクセスすると同じ例外が発生する

(. (FileChannel/MapMode) READ_ONLY) 

答えて

75

あなたは$

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

'import'関数や':import'キーワードでFileChannelをインポートする場合、 'FileChannel $ MapMode'をインポートしていることも忘れないでください。 –

+1

@TerjeDahlありがとうございます。私はこれを含めるためにあなたの質問を編集すべきだと思う、Hamza Yerlikaya。 – Joe

11

構文(FileChannel/MapMode)と内部クラスにアクセスするには、簡素化し、(フィールドに、あなたも、括弧を省略可能)静的フィールドとメソッドのためにのみ意図されています!また、...フォームは、フィールド/メソッド用ですが、ネスト/インナークラス用のフォームではありません!

JVMの場合、内部クラスOuter.Innerは、ちょうどOuter$Innerという名前のクラスです(コンパイラはこれに対してファイルOuter$Inner.classを作成します)。 Javaコンパイラでは、Outer.Innerで参照できます。 Outer$Innerという名前の非内部クラスを定義することもできます。このクラスには、Outer$Innerという参照があります。両方がOuter$Innerのクラス名必要がありますので、あなたが、しかし、同時に両方を定義することはできません(Outer$Inner.classと名付けられ、.classファイルを、ので、これは重複したクラス名になります!)

リフレクションを使用して - 例えばClass.forName() - 通常はある種の動的性を導入するために、インポートされたクラスのパッケージ名を省略することはできず、ドットの代わりに$の記号で実際のクラス名を使用する必要があります。

おそらくClojureは同じアプローチをとっているので、クラスがmy.packageの場合はmy.package.Outer$Innerという形式を使用する必要があります。既に外部クラスをインポートしていても!パッケージ名を回避するには、明示的に内部クラスmy.package.Outer$InnerをインポートしてOuter$Innerとしてそれを参照してください(その実際のクラス名!)しかし、あなたはそれをインポートすることにより、Innerにこれを減らすことはありませんすることができます

Innerはには意味がありませんJVMはJavaコンパイラだけでコンパイル時のコンテキストからのショートカットを提供します(これは実行時にClass.forNameのようなJVMでは利用できません)... OK ... Clojureではもちろん、常に次のように定義することができます:(def Inner Outer$Inner) ...または(def Tom Outer$Inner)または(def Harry Outer$Inner)または何でも...もしあなたがそれがより好きなら。

+0

これはおそらくいい説明です。どうも。 – tutysara

関連する問題