対象: オーバーロードされているJavaのメソッドを明示的に呼び出すJRubyからJavaオブジェクトを利用しているとき、オーバーロード(メソッド名が同じで引数が異なる)されているメソッドをうまく呼び出せなかったことはないだろうか。例えば、以下のコードではArrayList内のindex = 1の要素である"2"を削除したいのか、あるいはindex = 2の要素である"3"を削除したいのかという意図とは関係なく、index = 2の"3"が削除される。 require "java" al = java.util.ArrayList.new al.add(1) # index = 0 al.add(2) # index = 1 al.add(3) # index = 2 al.remove(2) al.to_array.each do |item| p item end 実行結果は以下である。つまり、JRubyはArrayListのremove(int index)メソッドを呼び出したのである。 [mobile@localhost ruby]$ jruby overload_test.rb 1 2 しかし、この動作だと"2"という要素を指定してremoveすることはできない。呼び出したいのはremove(Object o)メソッドである。JRuby 1.4以降では、java_methodメソッドを使うと利用したいメソッドを明示的に呼び出すことができる。
require "java" al = java.util.ArrayList.new al.add(1) # index = 0 al.add(2) # index = 1 al.add(3) # index = 2 # java_method :メソッド名, [引数型リスト] remove = al.java_method(:remove, [java.lang.Object]) remove.call(2) # 2を渡してremoveメソッド呼び出し al.to_array.each do |item| p item end このとき、java_methodメソッドに渡すメソッド名はRuby風のメソッド名ではなく、Javaのメソッド名であることに注意してほしい。例えば、getDataというメソッドを呼び出す場合、Ruby的にgetを省略して"data"ではなく、"getData"とJavaのメソッド名で記述しなければならない。 Javaオブジェクト.java_method(:Javaメソッド名, [引数の型の配列]) 以下が実行結果である。今度はindex = 2の要素ではなく"2"という要素が削除されているのが分かる。 [mobile@localhost ruby]$ jruby overload_test.rb 1 3 (2010/11/25)
Copyright(C) 2004-2014 モバイル開発系(K) All rights reserved.
[Home]
|