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

如何在Clojure中匹配Java方法签名,java,clojure,Java,Clojure,我正在使用Clojure的Java库。library cookbook介绍了一种静态方法,使用方法如下: List<String> myList = new ArrayList<String>(); // next, add values to list, then: myResults = JavaClass.staticMethod(myList); 但是当我执行此操作时,会收到错误消息“CompilerException java.lang.IllegalArgu

我正在使用Clojure的Java库。library cookbook介绍了一种静态方法,使用方法如下:

List<String> myList = new ArrayList<String>();
// next, add values to list, then:
myResults = JavaClass.staticMethod(myList);
但是当我执行此操作时,会收到错误消息“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) {
...
}
公共静态列表staticMethod(列表参数、对象…更多参数){
...
}

如果您使用的java库实际声明了如下方法:

public static Whatever staticMethod(List<String> xs) {...}
publicstaticmethod(List xs){…}
那么您所做的是正确的(事实上,您甚至可以跳过j.u.ArrayList调用,因为vectors也实现了List)。因此,要么你正在做与你所说的不同的事情,要么方法的声明与你试图使用它的方式不同


我打赌是后者:可能有一个varargs(
Foo…xs
)参数你没有提到吗?如果是这样,请参阅类似的内容以获得正确的方法。如果没有,那么请粘贴您试图调用的方法的确切签名,也许有人会发现。

如果您使用的java库实际声明了这样的方法:

public static Whatever staticMethod(List<String> xs) {...}
publicstaticmethod(List xs){…}
那么您所做的是正确的(事实上,您甚至可以跳过j.u.ArrayList调用,因为vectors也实现了List)。因此,要么你正在做与你所说的不同的事情,要么方法的声明与你试图使用它的方式不同


我打赌是后者:可能有一个varargs(
Foo…xs
)参数你没有提到吗?如果是这样,请参阅类似的内容以获得正确的方法。如果没有,那么,请粘贴您试图调用的方法的确切签名,也许有人会找到它。

对于这些情况,我通常的方法是在类上使用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 ....
main>(->[1 2 3]
java.util.ArrayList。
java.util.array/copyOf)
CompilerException java.lang.IllegalArgumentException:没有匹配的方法:copyOf,compileing:(*cider repl api*:49:24)
main>(->java.util.array
clojure.reflect/reflect
clojure.pprint/pprint)
{:bases{java.lang.Object},
:flags#{:public},
:成员
#{{:名称流,
:返回类型java.util.stream.stream,
:声明类java.util.Arrays,
:参数类型[java.lang.Object],
:异常类型[],
:flags#{:public:static}
……还有很多方法。。。
{:名称副本,
:返回类型java.lang.Object,
:声明类java.util.Arrays,
:参数类型[java.lang.Object int java.lang.Class],
:异常类型[],
:flags#{:public:static}
……更多。。。。

对于这些情况,我通常的方法是在类中使用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 ....
main>(->[1 2 3]
java.util.ArrayList。
java.util.array/copyOf)
CompilerException java.lang.IllegalArgumentException:没有匹配的方法:copyOf,compileing:(*cider repl api*:49:24)
main>(->java.util.array
clojure.reflect/reflect
clojure.pprint/pprint)
{:bases{java.lang.Object},
:flags#{:public},
:成员
#{{:名称流,
:返回类型java.util.stream.stream,
:声明类java.util.Arrays,
:参数类型[java.lang.Object],
:异常类型[],
:flags#{:public:static}
……还有很多方法。。。
{:名称副本,
:返回类型java.lang.Object,
:声明类java.util.Arrays,
:参数类型[java.lang.Object int java.lang.Class],
:异常类型[],
:flags#{:public:static}
……更多。。。。

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

(-> ["vector" "of" "strings"]
 (JavaClass/staticMethod (into-array Object [nil])))

一切正常。

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

(-> ["vector" "of" "strings"]
 (JavaClass/staticMethod (into-array Object [nil])))

一切正常。

使用
JavaLibrary/staticMethod
,你是说
JavaClass/staticMethod
,其中
JavaClass
属于
JavaLibrary
?@MicSokoli完全正确。经过适当编辑。使用
JavaLibrary/staticMethod
,你是指
JavaClass/staticMethod
,其中
JavaClass
属于
JavaLibrary
?@MicSokoli,完全正确。经过适当编辑。