JRuby - Java Integration
出典: Wiki@browncat.org
目次 |
[編集] Java Integration (日本語訳)
[JRuby - Java Integration](原文) 勝手に訳していいのかわかりませんが、ざくっと適当に訳してみました。
[編集] Javaサポート概要
JRubyはVersion 0.5.2から新しいJavaクラスを読み込み、使うためのインターフェースを持ちます。
[編集] 目標
Javaのクラスの利用をできるだけ簡単にするためには、それらは理想的にRubyのクラスと同じように振舞わなければなりません。ほとんどの場合これはうまく働きますが、全ての目的で正しく動かないことには妥協せざるを得ません。古いJavaサポートは最初の問題は解決しましたが、さらに制御が必要な場合の解決方法を提供しませんでした。新しいJavaサポートの設計目標は古いJavaサポートのシンプルさを失わずに、必要な場合には全てをコントロールできる低レベルなアクセスを許すことです。
[編集] デザイン
Javaサポートは"低レベル"と"高レベル"の二つに分かれています。 低レベル層はJavaのリフレクションクラス(java.lang.reflection.*とjava.lang.Class)への薄いラッパーとしてJavaで実装されています。 その上に高レベル層が全てRubyで構築されています。
[編集] 低レベル
JavaリフレクションAPIに慣れていればこのAPIを理解することはおそらく簡単でしょう。
Rubyのコードで使われる全てのJavaオブジェクトはJavaObjectインスタンスにラップされています。これら単体では大したことは出来ませんが、JavaMethodインスタンスと一緒に使うことでメソッド呼び出しが出来ます:
java_method.invoke(java_object, arg1, arg2)
JavaClass、JavaMethodとJavaFieldはJavaクラスの情報を得るために使われます。どのmethodとfieldを持つのか、どんなインターフェースをインプリメントするのか、finalであるのか、staticなのかpublicなのか。ぎこちない方法ではあるがJava自体で出来る全てのことがこの低レベルAPIで出来るでしょう。
[編集] 高レベル
生のJavaObjectはスクリプティングにはそう便利ではありません。そこで代わりにJavaProxyを使います。 これは実際のJavaObjectのjavaメソッドに対応しています。 全てのこれらのメソッドの一つに対する呼び出しは低レベルの'invoke'メソッドを介して行うように実装されます。 高レベルAPIを使うとき、全ての戻り値がJavaProxyでラップされるので、ほとんどJavaObjectを見ることはないでしょう。
スクリプトの開発者がしなければならないのは高レベルサポートを読み込むことと、欲しいJavaパッケージをRubyクラスもしくはモジュールにインクルードすることです:
require 'java' # 高レベルJavaサポートの読み込み module Foo include_package 'java.util' # java.utilの中のクラスがこのモジュール内で有効になります r = Random.new # java.util.Randomのインスタンスを生成 puts r.nextInt # 出力に乱整数を書き込みます end
ruby 0.8からは, この例は以下のように書き直すことが出来ます。
require 'java' include_class 'java.util.Random' r = Random.new puts r.nextInt
どちらの例でもJavaのメソッドnextInt()からの戻り値である'int'は自動的にFixnumに変換されています。この自動的な変換は数値、論理値、文字列に対して双方向に行われます。しかし、コレクションと配列に対し古いJavaサポートが行ったような自動変換は行われません。
最初の例と異なり、二つ目の例はRamdomを直接トップレベルにインポートしています。(ところが最初の例はパッケージの全てをトップレベルでないモジュールに読み込まなくてはなりません)
