7

对关于 Clojure-Java 互操作的一个非常古老的问题的回答解释了如何使用gen-classand:state关键字:init来创建可从 Java 访问的单个公共实例变量。如果您只需要一条数据可供 Java 类使用,或者如果您可以要求 Java 类使用读取例如存储在状态变量中的映射的访问器函数,这就足够了。此方法还允许数据更改,例如通过将atoms 存储在状态变量中。

如果我想创建多个在 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. 无论如何,我看不到如何初始化barbaz使用init函数。

4

1 回答 1

3

gen-class宏不支持定义多个公共字段。您必须改用defrecord宏或deftype宏。

(defrecord Foo [bar baz])

不幸的是,defrecord宏和deftype宏都没有准备一种方法来定义它们的构造函数。因此,在必须初始化多个实例变量的情况下,用 Java 编写 Java 类并不丢人。

于 2015-05-02T04:00:52.670 回答