互操作如何将类型化集合从clojure传递到java?
我知道clojure/java互操作的基础知识:从clojure调用java,反之亦然。然而,我无法将类型化集合从clojure返回到java。我试图从调用clojure的java代码中看到这种性质的东西
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] ????])
让我们考虑使用CuljuleAPI编写一个API,它将被分配为JAR文件,用于java。我的问题是如何通过什么来代替????上面的问题标记在AOT的:gen类中,因此程序员使用我的api在java中编写一段代码时,可以从eclipse中获得适当的intellisense/代码完成(例如:createListofTypedObjects() returns List<TypedObject>
)
# 1 楼答案
您不需要担心Clojure中的泛型(类型化集合)。泛型实际上只是Java编译器的类型提示。在运行的Java程序中,
List<String>
实际上与List<Object>
相同例如,一个包含字符串的Clojure向量已经是一个
List<String>
,不需要转换# 2 楼答案
其他人是对的,Clojure不确保返回集合中的元素类型,等等(实际上,JVM也不确保集合中的元素类型——这完全由javac处理)
然而,我可以看到向其他Java程序员提供API的价值,该API指定了一个接口,该接口声明以各种方式参数化的返回值(或参数);如果希望在现有Java环境中使用Clojure而不引起轰动,这一点尤其有吸引力
目前,这需要两个步骤:
gen-class
名称空间(或proxy
或reify
实例),使其实现该接口(Clojure确实提供了一个
definterface
表单,允许您避免单独的Java接口定义,但是definterface
,就像Clojure的其余部分一样,不提供指定参数化类型的功能。也许有一天…:-)例如
然后是gen类名称空间:
当用户创建
FooImpl
的实例时,他们将获得代码完成,表明该方法返回List<TypedObject>
,而不是Object
或未经参数化的List
类型如果您使用的是sane构建工具(例如maven、gradle或正确配置的ant),那么您可以将Java接口放在Clojure项目中,跨语言依赖性将得到解决