我在Java代码中有以下类:
public class CHRTreeCreator extends IndexCreator { ... }
相反CHRTreeCreator
我想使用不同的实现,它也扩展了IndexCreator
,但我希望在 JRuby 中对其进行编码。问题是,IndexCreator
的具体实现是基于xml配置文件选择的:
<creator>dwe.index.tree.chr.CHRTreeCreator</creator>
代码如下所示:
// className is fetched from XML
Class creatorClass = Class.forName(className);
Constructor constructor = creatorClass.getConstructor(new Class[] { });
creator = (IndexCreator) constructor.newInstance(new Object[] { });
问题是,是否可以在Ruby中实现它,如下所示:
class MyIndexCreator < IndexCreator
end
以某种方式将MyIndexCreator
类名放入XML配置文件中。在这种情况下,模块 - 包映射如何工作?
如果无法通过Java的Class.forName加载Ruby类,我该如何解决这个问题呢?
答案 0 :(得分:5)
目前,JRuby子类不能通过Java以这种方式访问,尽管它计划在某种程度上用于未来的实现(也许是JRuby 1.5)。
一个选项(取决于您班级的API)是创建一个委托:
public class RubyIndexCreator extends IndexCreator {
private IndexCreator rubyCreator;
public RubyIndexCreator() {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("ruby");
FileReader r = new FileReader("ruby_index_creator.rb");
try {
rubyCreator = engine.eval(r);
}
finally {
r.close();
}
}
public Object create(String someArg) {
return rubyCreator.create(someArg);
}
}
我已经掩饰了一些缓存的机会,并且还勾勒出管理文件阅读器,但希望你能得到它。
在这个特定示例中,ruby_index_creator.rb
将实现您的索引创建者类,然后返回它的实例 - 显然,从这里您可以引用其他ruby文件,并根据需要进行组织:
class MyIndexer < IndexCreator
[...]
end
MyIndexer.new
就是这样!
答案 1 :(得分:0)
作为替代方案,也许您可以利用Ruby的Open Classes并直接修改CHRTreeCreator的行为(而不是子类)。
答案 2 :(得分:0)
如何使用ruby eval:
C:\>jirb
irb(main):001:0> require 'java'
=> false
irb(main):002:0> class MyDate < Java::JavaUtil::Date
irb(main):003:1> def my_method;puts "hi there";end
irb(main):004:1> end
=> nil
irb(main):005:0>
irb(main):006:0* c = "MyDate"
=> "MyDate"
irb(main):007:0> obj = eval("#{c}.new")
=> #<MyDate:0xd2efa1>
irb(main):008:0> obj.my_method
hi there
=> nil
irb(main):009:0>