首页 > 解决方案 > 从 Java 调用 Clojure:为什么“新”样式 (clojure.java.api.Clojure) 比“旧”样式 (gen-class) 更好?

问题描述

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

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

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

标签: clojureclojure-java-interop

解决方案


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

  1. 使用 clojure.lang.RT 中的方法来初始化运行时,加载文件,然后查找 var。这是旧的,已弃用的方法。
  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 类的废话。


推荐阅读