如何在Clojure中匹配Java方法签名

时间:2016-03-16 16:34:54

标签: java clojure

我正在使用Clojure的Java库。库食谱描述了一种静态方法,其使用方法如下:

List<String> myList = new ArrayList<String>();
// next, add values to list, then:
myResults = JavaClass.staticMethod(myList);

最初,我认为我可以通过执行以下操作来使用Clojure中的方法:

(-> ["vector" "of" "strings"]
  java.util.ArrayList.
  JavaClass/staticMethod)

但是当我这样做时,我收到错误消息“CompilerException java.lang.IllegalArgumentException:No matching method:staticMethod”。

我唯一能看到我做错的是,在cookbook示例中,ArrayList被声明为List类型,虽然ArrayList实现了List接口,但我没有在Clojure代码中明确地这样做。我的Java-fu并不那么强大,所以我是否正确理解了方法签名在Java中的工作方式?

编辑:正如下面的答案之一所暗示的,该方法是可变的。它的格式为

public static List<String> staticMethod(List<String> args, Object... moreArgs) {
...
}

3 个答案:

答案 0 :(得分:4)

如果你正在使用的java库实际上声明了这样的方法:

public static Whatever staticMethod(List<String> xs) {...}

然后你正在做的是正确的(实际上你甚至可以跳过j.u.ArrayList调用,因为矢量也实现了List)。所以,要么你做的不同于你所说的你正在做的事情,要么宣布这个方法与你尝试使用它的方式不同。

我的赌注是后者:或许还有一个你没有提到的varargs(Foo... xs)论点?如果是这样,请查看How to handle java variable length arguments in clojure?之类的内容以获得正确的方法。如果没有,那么请粘贴您尝试拨打的方法的确切签名,也许有人会想出来。

答案 1 :(得分:2)

我对这些情况的常用方法是在课堂上使用clojure.reflect / refelct,看看它真正期待什么

main> (-> [1 2 3]
          java.util.ArrayList.
          java.util.Arrays/copyOf)
CompilerException java.lang.IllegalArgumentException: No matching method: copyOf, compiling:(*cider-repl api*:49:24) 

main> (-> java.util.Arrays
          clojure.reflect/reflect
          clojure.pprint/pprint)
{:bases #{java.lang.Object},
 :flags #{:public},
 :members
 #{{:name stream,
    :return-type java.util.stream.Stream,
    :declaring-class java.util.Arrays,
    :parameter-types [java.lang.Object<>],
    :exception-types [],
    :flags #{:public :static}}

.... lots more methods ...

   {:name copyOf,
    :return-type java.lang.Object<>,
    :declaring-class java.util.Arrays,
    :parameter-types [java.lang.Object<> int java.lang.Class],
    :exception-types [],
    :flags #{:public :static}}

.... lots more ....

答案 2 :(得分:1)

当用户 amalloy 在他们的回答中指出时,你不能在从Clojure调用时忽略Java varargs参数。当我将代码更改为:

(-> ["vector" "of" "strings"]
 (JavaClass/staticMethod (into-array Object [nil])))
一切都按预期工作。