我想在 JRuby 中调用 Java 类的静态方法。目前为了实现这一点,我使用:
class_name = "com.slackworks.naether.util.LogUtil"
clazz = eval(class_name)
clazz.setLogLevel( "debug" )
必须使用 eval 将字符串转换为类似乎很笨拙。我环顾四周,但找不到 JRuby 助手来代替
eval
。
我需要将字符串转换为类的原因是,这种情况发生在通过 JRuby 或 RJB 处理请求的包装器中,具体取决于 Ruby 运行时。如果 Ruby 运行时使用 RJB,则调用将类似于:
class_name = "com.slackworks.naether.util.LogUtil"
clazz = Rjb::import( class_name )
clazz.setLogLevel( "debug" )
所以我通过查看JRuby Wiki偶然发现了一个解决方案。
Java::JavaClass.for_name
可用于将String转换为Java类,可以使用ruby_class
将其转换为Ruby类。使用 IRB 的示例:
jruby-1.6.8 :053 > math_class = Java::JavaClass.for_name("java.lang.Math").ruby_class
=> Java::JavaLang::Math
jruby-1.6.8 :054 > math_class.floor( 10.7 )
=> 10.0
你看过https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby吗?特别是,
java_import
应该允许您执行此操作。
$ jruby -S irb
irb(main):001:0> java_import 'java.util.concurrent.TimeUnit'
=> [Java::JavaUtilConcurrent::TimeUnit]
irb(main):002:0> TimeUnit.values
=> java.util.concurrent.TimeUnit[NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS]@46150133
在上面的示例中,您应该能够执行以下操作:
require 'java'
java_import class_name
LogUtil.setLogLevel "debug"
如果您想加载/获取代理类而不实际将其挂接到您的命名空间中,您可以使用:
str_class = JavaUtilities.get_proxy_class("java.lang.String")
请注意:这仅在某些情况下有用,如果可能,请使用正常的
java_import
。
如果您使用的是 Rails,您还可以使用 Constantize。
"Java::JavaLang::Math".constantize
=> Java::JavaLang::Math