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

时间:2014-04-16 23:01:51

标签: java ruby jruby

拥有一个带有重载方法的Java类:

public void test(float x) {

}

public void test(RubyArray array) {

}

在Ruby中,

object.test(1.0)

工作正常。但是:

object.test([1.0,2.0])

将崩溃并显示消息:

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中使用它们,所以我猜这个问题主要与RubyArray参数本身有关 - 虽然我没有看到这个问题。

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


我正在使用JRuby 1.7.11,在Eclipse Kepler for Mac上构建我认为Java SE 6的内容。


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

这有效:

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;\n" + "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);
    }
}

这不起作用:

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;\n" + "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);
    }
}

2 个答案:

答案 0 :(得分:1)

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

因此,当你调用test-method时,它会翻转,它只需要第一种方法(不知道它是如何或为什么搜索或找到带有int-param的方法)。

另请参阅此答案:Why doesn't ruby support method overloading?

答案 1 :(得分:1)

您可以使用java_send(方法名称符号),(类型数组),* args指定类型,例如:

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

对于没有发送数组的多个args,顺便说一句,它看起来就像CallingJavaFromJRuby中的这个例子:

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