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

时间:2022-12-06 22:49:52

Basically what I need to do is this

基本上我需要做的就是这个

FileChannel.MapMode.READ_ONLY

I tried doing the obvious

我试着做了显而易见的事

(.. FileChannel MapMode READ_ONLY)

but that ends up throwing an exception

但这最终导致了一个例外

java.lang.NoSuchFieldException: MapMode

even the / notation specified as for access static fields in the interop documentation produces the same exception

甚至在interop文档中为访问静态字段指定的/标记也会产生相同的异常。

(. (FileChannel/MapMode) READ_ONLY)

2 个解决方案

#1


78  

You access inner classes with $

使用$访问内部类

java.nio.channels.FileChannel$MapMode/READ_ONLY

#2


11  

The syntax (FileChannel/MapMode) is a simplification and intended only for static fields and methods (for fields, you may even omit the parentheses)! Also the . and .. forms are for fields/methods but NOT for nested/inner classes!

语法(FileChannel/MapMode)是一种简化,只用于静态字段和方法(对于字段,甚至可以省略括号)!还的。和. .表单用于字段/方法,但不用于嵌套/内部类!

For the JVM, an inner class Outer.Inner is just a class named Outer$Inner (and the compiler creates a file Outer$Inner.class for this). The Java compiler lets you refer to it by Outer.Inner. You can also define a not-inner class named Outer$Inner to which the compiler lets you refer as Outer$Inner. You cannot define both at the same time, however, since both would have class names of Outer$Inner (and .class files named Outer$Inner.class, so this would be a duplicate class name!)

对于JVM,内部类外层。Inner是一个名为Outer$Inner的类(编译器创建一个文件Outer$Inner。类的)。Java编译器允许您通过Outer.Inner引用它。您还可以定义一个名为Outer$Inner的非内部类,编译器可以将其称为外部$Inner。但是,您不能同时定义这两个文件,因为这两个文件都有外部$Inner的类名(以及名为Outer$Inner的.class文件)。类,所以这是一个重复的类名!)

When using reflection - e.g. with Class.forName() - (usually to introduce some dynamicity) you cannot omit the package name of an imported class and you must use the real class name with the $ sign instead of a dot.

当使用反射时(例如使用class . forname()))(通常是为了引入一些动态特性),您不能忽略一个导入类的包名,必须使用带有$符号而不是点的真正类名。

Probably for its dynamic nature, Clojure takes the same approach, so you need to use the form my.package.Outer$Inner if the class is in my.package - even if you imported the outer class already! To avoid the package name, you can explicitly import the inner class my.package.Outer$Inner and then refer to it as Outer$Inner (its real class name!) but you will not reduce this to Inner by just importing it:

由于Clojure具有动态特性,所以您需要使用form my.package。如果这门课在我的课上,外$Inner。包-即使您已经导入了外部类!为了避免包名,可以显式导入内部类my.package。外部$Inner,然后将其称为外部$Inner(它的真正类名!)

Inner has no meaning to the JVM, just the Java-Compiler offers you this shortcut from the compile time context (which is NOT available to the JVM and methods like Class.forName at runtime!) ... OK, in Clojure you could, of course, always define: (def Inner Outer$Inner) ... or (def Tom Outer$Inner) or (def Harry Outer$Inner) or whatever ... if you like that better.

Inner对JVM没有意义,只有java编译器从编译时上下文(JVM和类之类的方法不能使用这个快捷方式)提供这个快捷方式。在运行时forName !)…当然,在Clojure中,您可以始终定义:(def Inner Outer$Inner)…或者(def Tom Outer$Inner)或者(def Harry Outer$Inner)或者其他什么……如果你喜欢的话。

#1


78  

You access inner classes with $

使用$访问内部类

java.nio.channels.FileChannel$MapMode/READ_ONLY

#2


11  

The syntax (FileChannel/MapMode) is a simplification and intended only for static fields and methods (for fields, you may even omit the parentheses)! Also the . and .. forms are for fields/methods but NOT for nested/inner classes!

语法(FileChannel/MapMode)是一种简化,只用于静态字段和方法(对于字段,甚至可以省略括号)!还的。和. .表单用于字段/方法,但不用于嵌套/内部类!

For the JVM, an inner class Outer.Inner is just a class named Outer$Inner (and the compiler creates a file Outer$Inner.class for this). The Java compiler lets you refer to it by Outer.Inner. You can also define a not-inner class named Outer$Inner to which the compiler lets you refer as Outer$Inner. You cannot define both at the same time, however, since both would have class names of Outer$Inner (and .class files named Outer$Inner.class, so this would be a duplicate class name!)

对于JVM,内部类外层。Inner是一个名为Outer$Inner的类(编译器创建一个文件Outer$Inner。类的)。Java编译器允许您通过Outer.Inner引用它。您还可以定义一个名为Outer$Inner的非内部类,编译器可以将其称为外部$Inner。但是,您不能同时定义这两个文件,因为这两个文件都有外部$Inner的类名(以及名为Outer$Inner的.class文件)。类,所以这是一个重复的类名!)

When using reflection - e.g. with Class.forName() - (usually to introduce some dynamicity) you cannot omit the package name of an imported class and you must use the real class name with the $ sign instead of a dot.

当使用反射时(例如使用class . forname()))(通常是为了引入一些动态特性),您不能忽略一个导入类的包名,必须使用带有$符号而不是点的真正类名。

Probably for its dynamic nature, Clojure takes the same approach, so you need to use the form my.package.Outer$Inner if the class is in my.package - even if you imported the outer class already! To avoid the package name, you can explicitly import the inner class my.package.Outer$Inner and then refer to it as Outer$Inner (its real class name!) but you will not reduce this to Inner by just importing it:

由于Clojure具有动态特性,所以您需要使用form my.package。如果这门课在我的课上,外$Inner。包-即使您已经导入了外部类!为了避免包名,可以显式导入内部类my.package。外部$Inner,然后将其称为外部$Inner(它的真正类名!)

Inner has no meaning to the JVM, just the Java-Compiler offers you this shortcut from the compile time context (which is NOT available to the JVM and methods like Class.forName at runtime!) ... OK, in Clojure you could, of course, always define: (def Inner Outer$Inner) ... or (def Tom Outer$Inner) or (def Harry Outer$Inner) or whatever ... if you like that better.

Inner对JVM没有意义,只有java编译器从编译时上下文(JVM和类之类的方法不能使用这个快捷方式)提供这个快捷方式。在运行时forName !)…当然,在Clojure中,您可以始终定义:(def Inner Outer$Inner)…或者(def Tom Outer$Inner)或者(def Harry Outer$Inner)或者其他什么……如果你喜欢的话。