defprotocol
每个 Clojure 协议也是一个具有相同名称和方法的 Java 接口。如果我以ibm developerworks为例,我们会看到:
(ns com.amalgamated)
(defprotocol Fulfillment
(invoice [this] "Returns an invoice")
(manifest [this] "Returns a shipping manifest"))
相当于:
package com.amalgamated;
public interface Fulfillment {
public Object invoice();
public Object manifest();
}
Clojure.org也有这方面的一些(相当简洁的)信息。
希望参与协议的 Java 客户端可以通过实现协议生成的接口最有效地做到这一点。可以使用扩展构造提供协议的外部实现(当您希望不在您的控制范围内的类或类型参与协议时需要):
(extend AType AProtocol
{:foo an-existing-fn
:bar (fn [a b] ...)
:baz (fn ([a]...) ([a b] ...)...)} BProtocol
{...} ...)
definterface
如果你的目标是性能,你可以考虑使用definterface
,它的使用类似于协议。此SO 帖子还包含有关如何使用它的详细信息:
(definterface Foo
[^int foo [x ^String y]]
[^void bar [^ints is]])
definterface
似乎比协议更快。
defrecord
同样,record
s(以及deftype
and definterface
)将生成 Java 类。同样,Clojure.org/datatypes有有用的信息(强调我的):
deftype 和defrecord为具有一组给定字段的命名类动态生成编译的字节码
,并且可选地,为一个或多个协议和/或接口生成方法。它们适用于动态和交互式开发,不需要 AOT 编译,并且可以在单个会话过程中重新评估。它们在生成具有命名字段的数据结构方面类似于 defstruct,但与 defstruct 的不同之处在于:[...]
所以是的,如果可以从 Java 获得。只是要小心命名。
作为旁注,您可能想看看从 Java 调用 Clojure。