如何通过Clojure互操作访问静态内部Java类?
基本上我需要做的是如何通过Clojure互操作访问静态内部Java类?,java,interop,clojure,Java,Interop,Clojure,基本上我需要做的是 FileChannel.MapMode.READ_ONLY 我试着做显而易见的事 (.. FileChannel MapMode READ_ONLY) 但这最终引发了一个异常 java.lang.NoSuchFieldException: MapMode 即使在中为访问静态字段指定的/符号也会产生相同的异常 (. (FileChannel/MapMode) READ_ONLY) 您可以使用$ java.nio.channels.FileChannel$MapMode/
FileChannel.MapMode.READ_ONLY
我试着做显而易见的事
(.. FileChannel MapMode READ_ONLY)
但这最终引发了一个异常
java.lang.NoSuchFieldException: MapMode
即使在中为访问静态字段指定的/
符号也会产生相同的异常
(. (FileChannel/MapMode) READ_ONLY)
您可以使用$
java.nio.channels.FileChannel$MapMode/READ_ONLY
请注意,如果要导入FileChannel
,还应导入FileChannel$MapMode
语法(FileChannel/MapMode)
是一种简化,仅用于静态字段和方法(对于字段,甚至可以省略括号)!还有
和。
表单用于字段/方法,但不用于嵌套/内部类
对于JVM,内部类Outer.inner
只是一个名为Outer$inner
的类(编译器为此创建一个文件Outer$inner.class
)。Java编译器允许您通过Outer.internal
引用它。您还可以定义名为Outer$inner
的非内部类,编译器允许您将其称为Outer$inner
。但是,您不能同时定义这两个类,因为这两个类的类名都是Outer$Inner
(而.class
文件名为Outer$Inner.class
,因此这将是一个重复的类名!)
当使用反射时(例如使用Class.forName()
-(通常是为了引入一些动态性),不能忽略导入类的包名,必须使用带有$
符号的真实类名,而不是点
可能是因为它的动态特性,Clojure采用了相同的方法,因此如果类位于my.package
中,则需要使用my.package.Outer$Inner>格式,即使您已经导入了外部类!为了避免使用包名,您可以显式导入内部类my.package.Outer$inner
,然后将其称为Outer$inner
(其真实类名!),但您不会通过仅导入它而将其简化为inner
:
internal
对JVM没有任何意义,只是Java编译器从编译时上下文为您提供了此快捷方式(JVM和运行时的Class.forName
等方法不可用!)。。。当然,在Clojure中,您可以始终定义:(def-Inner-Outer$Inner)
。。。或(def Tom Outer$Inner)
或(def Harry Outer$Inner)
或其他任何。。。如果您喜欢的话。不要忘记,如果您使用导入
功能或:导入
关键字导入FileChannel,您还必须指定您正在导入FileChannel$MapMode
谢谢@TerjeDahl。Hamza Yerlikaya,我认为你应该编辑你的问题,将其包括在内。这是一个非常古老的问题,但为了以防万一,这条评论节省了一些时间:导入那些嵌套类时,你必须确保嵌套类是在你从中导入的类中定义的。如果嵌套类是继承的,则必须从父类导入它。