关于ruby:为什么JRuby在重载时不能使用参数为RubyArray的Java方法?

Why can't JRuby use my Java method whose parameter is a RubyArray when it is overloaded?

有一个具有重载方法的Java类:

1
2
3
4
5
6
7
public void test(float x) {

}

public void test(RubyArray array) {

}

在红宝石中,

1
object.test(1.0)

工作正常。然而:

1
object.test([1.0,2.0])

将崩溃并显示以下消息:

1
2
3
4
org.jruby.exceptions.RaiseException: (NameError) no method 'test' for arguments (org.jruby.RubyArray) on Java::MyNamespace::MyClass
  available overloads:
    (org.jruby.RubyArray)
    (int)

但是,正如你所看到的,这没有任何意义。它告诉我,我的RubyArray类型的参数没有方法,然后它立即告诉我,RubyArray类型的参数有一个可用的重载。

有趣的是,如果移除(int)重载,这就可以正常工作,也就是说,如果接受RubyArray的方法没有其他重载,它就可以正常工作。

我已经创建了许多超载的Java方法并在Ruby中使用过,因此我猜想,问题主要与EDCOX1 0参数本身有关,尽管我没有看到这个问题。

为什么?我在这里做错什么了?

我使用的是JRuby 1.7.11,我认为是eclipse开普勒上的Java SE 6,用于Mac。

为了便于测试,可以运行以下两个程序:

这项工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import javax.script.*;

import org.jruby.RubyArray;

public class Main {
    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        Main app = new Main();
    }
    public Main() throws ScriptException, NoSuchMethodException {
        ScriptEngine jruby = new ScriptEngineManager().getEngineByName("jruby");
        jruby.eval("include Java;
"
+"def start(main) main.test([1,2,3]); end");
        Invocable invocable = (Invocable)jruby;
        invocable.invokeFunction("start",this);
    }
    public void test(RubyArray array) {
        System.out.println(array);
    }
}

这不起作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import javax.script.*;

import org.jruby.RubyArray;

public class Main {
    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        Main app = new Main();
    }
    public Main() throws ScriptException, NoSuchMethodException {
        ScriptEngine jruby = new ScriptEngineManager().getEngineByName("jruby");
        jruby.eval("include Java;
"
+"def start(main) main.test([1,2,3]); end");
        Invocable invocable = (Invocable)jruby;
        invocable.invokeFunction("start",this);
    }
    public void test(int x) {
        System.out.println(x);
    }
    public void test(RubyArray array) {
        System.out.println(array);
    }
}


您可以使用java_send(方法名称符号)、(类型数组)、*参数(例如:

1
object.java_send :test, [RubyArray], [1.0,2.0]

对于不发送数组(btw)的多个参数,从callingjavafromjruby可以看到如下示例:

1
list.java_send :add, [Java::int, java.lang.Object], 0, 'foo'


我认为这是因为在Ruby中,不能用相同数量的参数重载方法,因为没有数据类型声明。您只能用不同数量的参数重载方法:public void test(int x)public void test(RubyArray arr, int x)

所以当你调用这个测试方法时,它就会弹出,只需要第一个方法(不知道如何或者为什么它会搜索或者找到带有int参数的方法)。

另请看这个答案:为什么Ruby不支持方法重载?