[英]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而不制造波浪,这一点尤其具有吸引力。
这目前需要两个步骤:
gen-class
名称空间(或proxy
或reify
实例),以便它实现该接口 (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.