繁体   English   中英

如何通过 Clojure 互操作访问静态内部 Java 类?

[英]How to access static inner Java class via Clojure interop?

基本上我需要做的是这个

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.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 编译器从编译时上下文中为您提供了这个快捷方式(JVM 和Class.forName等方法在运行时不可用!)...好的,在 Clojure 中,您可以,当然,总是定义: (def Inner Outer$Inner) ... 或(def Tom Outer$Inner)(def Harry Outer$Inner)或其他任何......如果你更喜欢那个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM