从 Java 调用 Clojure:为什么“新”风格(clojure.java.api.Clojure)比“旧”风格(gen-class)更好?

Jor*_*e D 1 clojure clojure-java-interop

在阅读了相关问题的这个很好的答案后,有些事情让我感到困惑:

有两种可能性可以与 Java 开发人员共享我在 Clojure 中编写的函数

  • 第一个是在 JAR 文件中提供它,以便他们可以像我用 Java 编写它一样调用它。听起来很适合 Clojure 倡导。

  • 第二种,据称是更好的方法,要求那些 Java 开发人员使用诸如clojure.lang.IFnor 之类的东西,clojure.lang.RT并通过将它们的名称作为字符串 (!) 传递而不是仅仅调用它们来调用函数。

为什么第二种方法“更好”?

ama*_*loy 7

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

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

您仍然可以执行 (3) -它完全没有问题。但是 gen-class 是一个相当笨重的工具,除了像暴露一些静态方法这样最简单的例子外,它并没有多少乐趣,而且使用 Clojure 提供一个“感觉”像 Java API 的 API 并不容易.

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

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