java - 如何使用 Clojure 的 gen-class 创建多个 Java 成员变量

标签 java clojure clojure-java-interop

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 将不会编译——编译器似乎随机创建 barbaz作为 Foo 的状态变量,因此只有其中一个可用于 Bar。无论如何,我看不到如何使用 init 函数初始化 barbaz

最佳答案

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/

相关文章:

Java 控制台循环

clojure - java 实例与 Vars 的正确 clojure 绑定(bind)

clojure - 如何在 Clojure 中随机化列表?

clojure - 为什么 Clojure 比其他 JVM 语言更可热插拔?

clojure - 如何在 Clojure 中的传入类指针上调用静态方法?

java - 已签名的 Java 小程序无法访问本地文件系统

java - 在 javafx 中首先控制获取焦点

java - mockito 对带参数的方法不做任何贡献

concurrency - Clojure:用于 IO 的 future、agent 或 core.async