是否有可能在JRuby中重新定义Java类?

时间:2011-03-23 05:01:34

标签: jruby

如何在JRuby中重新定义现有的Java方法?现在可以重新定义Ruby方法。我问这个是因为当你写一些像

这样的东西
include Java

puts java.io.File.separator

并检查java,io和File,结果发现java和io的类型为“ruby module”,File是“class”。所以我想知道是否可以写这样的东西并期望它能够正常工作

module Java
    module JavaIoType
        class File
          class << self
                alias_method :old_sp, :separator
                def separator(*args)
                    Kernel.puts caller
                    old_sp(*args)
                end
            end
        end
    end
end

但事实并非如此:(

还有similar question的clojure。我只是想知道JRuby的答案是否会有所不同。

我知道这有点紧张,但无论如何我都在问它。

3 个答案:

答案 0 :(得分:1)

这对我有用(使用JRuby 1.6):

require 'java'
java_import 'java.io.File'

puts Java::JavaIo::File::separator

module Java
  module JavaIo
    class File
      class << self
        alias_method :old_sp, :separator
        def separator(*args)
          Kernel.puts caller
          old_sp(*args)
        end
      end
    end
  end
end

puts Java::JavaIo::File::separator

输出:

\
test_io.rb:20:in `(root)'
\

答案 1 :(得分:0)

我不是这方面的专家,但根据我的理解,Java方法无法从JRuby重新定义,因为它已经编译过。

由于其动态特性,您只能在ruby中完全自由地重新定义方法。

我相信通过继承的正常覆盖方法将起作用。您可以对其进行子类化并覆盖该行为。但在你的情况下,你正在重新定义静态方法,所以这个选项也是不可能的。

但重新定义对象方法方法将适用于某些monkey patching。这些方法仅适用于JRuby。

答案 2 :(得分:0)

有效。

require 'rubygems'
require "java"

java_import "java.io.File" do 
  :JavaFile
end

class JavaFile

   alias_method :old_getName, :getName

   def getName()
        Kernel.puts caller
        old_getName()
    end

end

x = JavaFile.new('HelloFile.txt')

puts(x.getName())

可是:

它只适用于犹豫不决的一面。

BTW:separator是一个静态字符串而不是方法。