Ответ 1
Каждый 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
, использование которого аналогично протоколам. Этот сообщение SO также содержит сведения о том, как его использовать:
(definterface Foo
[^int foo [x ^String y]]
[^void bar [^ints is]])
definterface
кажется быстрее, чем протоколы.
Аналогично, record
(а также deftype
и definterface
) будут генерировать Java-классы.
Опять же, Clojure.org/datatypes имеет полезную информацию (внимание мое):
deftype и defrecord динамически генерирует скомпилированный байт-код для с именем class с набором заданных полей и, необязательно, методов для один или несколько протоколов и/или интерфейсов. Они подходят для динамического и интерактивное развитие, не нужно компилировать AOT, и может быть переоценена в ходе одного сеанса. Они похожи на defstruct в создании структур данных с именованными полями, но отличаются из defstruct в том, что: [...]
Итак, да, если будет доступно с Java. Просто будьте осторожны с наименованием.
В качестве дополнительной заметки вы можете захотеть взглянуть на вызов Clojure из Java.