我的团队中有人正在编写一个ruby / cucumber测试,调用一个带有List<Long>
参数的java api。我正在努力帮助他,但我的愚蠢知识非常有限。每当调用带有List<Long>
的java方法时,java方法就会抛出某种类型转换异常,因为ArrayList包含所有ruby Fixnum
对象。
以下简化代码显示我总是得到一个Fixnum而不是Java :: JavaLang :: Long
irb(main):017:0> java.util.ArrayList.new([12.to_java])[0].class
=> Fixnum
即使以下显示12.to_java生成Long
,也是如此irb(main):018:0> 12.class
=> Fixnum
irb(main):019:0> 12.to_java.class
=> Java::JavaLang::Long
我也尝试过不使用构造函数args
irb(main):020:0> a = java.util.ArrayList.new
=> #<Java::JavaUtil::ArrayList:0x314e60d2>
irb(main):021:0> a.add(12.to_java)
=> true
irb(main):022:0> a[0].class
=> Fixnum
直到直接实例化java.lang.Long
irb(main):023:0> a = java.util.ArrayList.new
=> #<Java::JavaUtil::ArrayList:0xfdcb343>
irb(main):024:0> a.add(java.lang.Long.new(12))
=> true
irb(main):025:0> a[0].class
=> Fixnum
我的最后一次尝试
irb(main):026:0> b = 12.to_java
=> #<Java::JavaLang::Long:0x244ff48e>
irb(main):027:0> b.class
=> Java::JavaLang::Long
irb(main):028:0> a = java.util.ArrayList.new
=> #<Java::JavaUtil::ArrayList:0x6a36ebaa>
irb(main):029:0> a.add b
=> true
irb(main):030:0> a.get(0).class
=> Fixnum
答案 0 :(得分:1)
实际上,这比你想象的要容易得多,如果只是传递一个[]
,它会很好用。)
在Ruby方面,JRuby确保值类似于Ruby,但当它到达Java端时 - 如果RubyArray实例传递给Java(实际上实现java.util.List
) - 它将自动转换“ toJava“在它最好。对于Ruby Fixnums,您将获得java.lang.Long
等操作的java.util.List#get
:
public class JavaAPI {
public void testListArgument(final List<Long> list) {
System.out.println("list = " + list + " list.class = " + list.getClass() + " list[0].class = " + list.get(0).getClass());
}
}
编译这个.java(在 target / classes 下)而不是像jruby -S irb
那样:
jruby-1.7.16 :007 > $CLASSPATH << 'target/classes'
=> ["file:/opt/local/rvm/rubies/jruby-1.7.16/lib/ruby/shared/readline/jline-2.11.jar", "file:/opt/local/rvm/rubies/jruby-1.7.16/lib/ruby/shared/readline/readline.jar", "file:target/classes/"]
jruby-1.7.16 :009 > Java::JavaAPI.new.testListArgument [1]
list = [1] list.class = class org.jruby.RubyArray list[0].class = class java.lang.Long
=> nil