簡體   English   中英

如何將類型化的集合從clojure傳遞給java?

[英]How to pass a typed collection from clojure to java?

我知道clojure / java interop的基礎知識:從clojure調用java,反之亦然。 但是,我無法將clojure中的類型集合返回給java。 我試圖從調用clojure的java代碼中看到一些自然的List<TypedObject>

Java Object:

public class TypedObject {
    private OtherType1 _prop1;
    public OtherType1 getProp1() {
        return _prop1;
    }
    public void setProp1(OtherType1 prop1) {
        _prop1 = prop1;
    }
}

CLojure method:

(defn -createListOfTypedObjects
      "Creates and returns a list of TypedObjects"
      [input]
      ;Do work here  to create and return list of TypedObjects
      [typedObj1, typedObj2, typedObj3])

(:gen-class
 :name some.namespace
 :methods [createListofTypedObjects[String] ????])

讓我們考慮一下,我正在使用clojure編寫一個API,它將作為jar文件分發,以便在java中使用。 我的問題是如何通過代替???? 上面的問題標記在:AOT的gen類中,以便程序員使用我的api在java中編寫一段代碼,可以從eclipse中獲得相應的intellisense / code completion(即: createListofTypedObjects() returns List<TypedObject> )例如。

其他是正確的,Clojure不能確保返回集合中的元素類型等。(實際上,JVM也不能確保集合中元素的類型 - 完全由javac處理。)

但是,我可以看到為其他Java程序員提供API的價值,這些程序員指定了一個接口,該接口聲明以各種方式參數化的返回值(或參數); 如果想要在現有的Java環境中使用Clojure而不制造波浪,這一點尤其具有吸引力。

這目前需要兩個步驟:

  • 定義一個單獨的接口(在Java中!),它可以根據需要指定參數化類型
  • 定義您的gen-class名稱空間(或proxyreify實例),以便它實現該接口

(Clojure確實提供了一個允許你避免單獨的Java接口定義的definterface形式,但是definterface ,就像Clojure的其余部分一樣,沒有提供指定參數化類型。也許有一天... :-))

例如

public interface IFoo {
    List<TypedObject> createListOfTypedObjects ();
}

然后你的gen-class命名空間:

(ns your.ns.FooImpl
  (:gen-class
    :implements [IFoo]))
(defn -createListOfTypedObjects
  []
  [typedObj1, typedObj2, typedObj3])

當您的用戶創建FooImpl實例時,他們將例如獲得代碼完成,指示該方法返回List<TypedObject>而不是Object或未參數化的List類型。

如果您正在使用理智的構建工具(例如maven ,gradle或正確配置的ant),那么您可以將Java接口放在Clojure項目中,並且將考慮跨語言依賴性。

如果您嘗試將類似List<String>傳遞給java方法,那么您不必擔心它。 類型參數(例如, String )僅用於javac編譯器,因此任何List在運行時都可以正常工作。

另一方面,如果您嘗試傳遞特定對象類型的數組(例如, String[] ),那么您可以使用各種-array函數:

user=> (make-array String 10)            ; an empty String array
#<String[] [Ljava.lang.String;@78878c4c>
user=> (into-array ["foo" "bar"])        ; array type inferred from first element
#<String[] [Ljava.lang.String;@743fbbfc>
user=> (into-array Number [1.2 5 7N])    ; explicit type array
#<Number[] [Ljava.lang.Number;@7433b121>

您不必擔心Clojure中的泛型(類型集合)。 泛型實際上只是Java編譯器的類型提示。 在正在運行的Java程序中, List<String>實際上與List<Object>相同。

因此,例如,包含字符串的Clojure向量已經是List<String> ,不需要轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM