从 Java 调用 Clojure:为什么 "new" 风格 (clojure.java.api.Clojure) 比 "old" 风格 (gen-class) 更好?

Calling Clojure from Java: Why is the "new" style (clojure.java.api.Clojure) better than the "old" one (gen-class)?

读完 this great answer to a related question 后有些事情让我感到困惑:

有两种方法可以与 Java 开发人员共享我用 Clojure 编写的函数

为什么是第二种方法"the better one"?

您在这里有点建立错误的二分法。每种方法都涉及创建一个 jar 文件:这就是 JVM 程序的分发方式。但是 Java 代码有 3 种不同的方式来调用包含在 jar 中的 Clojure 代码:

  1. 使用clojure.lang.RT中的方法来初始化运行时,加载文件,然后查找变量。这是旧的、已弃用的方法。
  2. 使用clojure.java.api.Clojure中的方法查找函数并调用它们。这是 (1) 的较新版本,隐藏了一些您可能不小心弄错的杂乱内容。
  3. 使用 Clojure 库中的 gen-class 来定义更 Java 友好的 Clojure 函数接口。

您仍然可以执行 (3) - 完全没有错。但是 gen-class 是一个非常笨重的工具,除了最简单的例子,比如公开一些静态方法,它没有太多乐趣,而且提供一个 API 并不容易 "feels" 就像 Java API 使用 Clojure。

但是您知道提供 API 感觉像 Java 的好处是什么吗? Java!因此,如果您想使 Clojure 库易于在 Java 中使用,我建议您在 Clojure 库中包含一些 Java 代码。您编写的 Java 代码弥合了语言鸿沟。它通过上面的机制 (2) 访问您的 Clojure 代码,并呈现一个 Java 友好的外观,因此外界不必知道底层有 Clojure。

amalloy/thrift-gen 是我多年前按照这种方法编写的库示例。用纯 Clojure 写这个一点也不容易,因为传统的 Java 习语对 Clojure 来说很陌生,而且它不能很好地支持它们。通过编写我自己的 Java shim,Java 客户可以获得一个非常舒适的界面来使用,我可以编写 Clojure 感觉像 Clojure 而不是一堆 gen-class 废话.