简体   繁体   English

如何强制JRuby使用Java Longs而不是Fixnums初始化Java ArrayList?

[英]How can I force JRuby to initialize a java ArrayList with java Longs instead of Fixnums?

Someone on my team is writing a ruby/cucumber test that calls a java api that takes a List<Long> argument. 我团队中的某人正在编写一个ruby / cucumber测试,该测试调用一个带有List<Long>参数的Java api。 I'm trying to help him out but my jruby knowledge is pretty limited. 我正在尝试帮助他,但是我对jruby的了解非常有限。 Whenever the call to the java method that takes List<Long> is made the java method is throwing some sort of class cast exception because the ArrayList contains all ruby Fixnum objects. 每当对采用List<Long>的java方法进行调用时,java方法都会引发某种类强制转换异常,因为ArrayList包含所有ruby Fixnum对象。

The following simplified code shows that I always get a Fixnum not a Java::JavaLang::Long 下面的简化代码显示我总是得到一个Fixnum而不是Java :: JavaLang :: Long

irb(main):017:0> java.util.ArrayList.new([12.to_java])[0].class
=> Fixnum

This is even though the following shows that 12.to_java produces a Long 即使以下内容显示12.to_java产生Long

irb(main):018:0> 12.class
=> Fixnum
irb(main):019:0> 12.to_java.class
=> Java::JavaLang::Long 

I've also tried not using the constructor args 我也尝试过不使用构造函数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

And gone as far a just instantiating a java.lang.Long directly 甚至直接实例化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

And my last attempt 我最后的尝试

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

actually, this is far easier than you think and will work fine if you just pass a [] around :) 实际上,这比您想象的要容易得多,如果只传递[]会很好用:)

while on the Ruby side JRuby makes sure values are Ruby-like but when it reaches the Java end - in case of a RubyArray instance passed to Java (which actually implements java.util.List ) - it will auto-convert "toJava" at it's best. 在Ruby方面,JRuby确保值类似于Ruby,但是当值到达Java端时(如果将RubyArray实例传递给Java(实际上实现了java.util.List ),它将在以下位置自动转换“ toJava”:最好 means for Ruby Fixnums you will get java.lang.Long on operations such as java.util.List#get : 对于Ruby Fixnums而言,您将在java.util.List#get操作上获得java.lang.Long

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());
    }
}

compile this .java (under target/classes ) than doing something like jruby -S irb : 编译这个.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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM