This answer关于 Clojure-Java 互操作的一个非常古老的问题解释了如何使用 gen-class
和 :state
和 :init
关键字来创建一个单一的可从 Java 访问的公共(public)实例变量。如果您只需要一个数据对 Java 类可用,或者如果您可以要求 Java 类使用访问器函数来读取,例如,存储在状态变量中的映射,这就足够了。此方法还允许更改数据,例如通过将 atom
存储在状态变量中。
如果我想创建多个在 Java 类中可直接读取的实例变量怎么办?这可能吗?例如,我可以编译以下文件并执行 Bar
类,然后看到 foo.bar
的值 42 被打印出来。
Foo.clj:
(ns students.Foo
(:gen-class
:name students.Foo
:state bar
; :state baz
:init init))
(defn -init
[]
[[] 42])
酒吧.java:
package students;
public class Bar {
public static void main(String[] args) {
Foo foo = new Foo();
System.out.println(foo.bar);
// System.out.println(foo.baz);
}
}
如果我取消注释 baz
行,Bar.java 将不会编译——编译器似乎随机创建 bar
或 baz
作为 Foo
的状态变量,因此只有其中一个可用于 Bar
。无论如何,我看不到如何使用 init
函数初始化 bar
和 baz
。
最佳答案
gen-class
宏不支持定义多个公共(public)字段。您必须改用 defrecord
宏或 deftype
宏。
(defrecord Foo [bar baz])
不幸的是,defrecord
宏和deftype
宏都没有准备一种方法来定义它们的构造函数。因此,在强制初始化多个实例变量的情况下,用 Java 编写 Java 类并不丢脸。
关于java - 如何使用 Clojure 的 gen-class 创建多个 Java 成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29991245/