JavaScript+Java:Rhinoの導入と基本的な利用法

白石俊平(あゆた)
2008-02-08 16:00:00
  • このエントリーをはてなブックマークに追加

他にもまだある!Javaクラスの参照方法

JavaImporterを使用したインポート

 importPackage()やimportClass()を用いてインポートを行うと、グローバルな名前空間に対してインポートされるので、クラス名の衝突が生じる可能性が高まります。同じ名前のクラスを二度インポートすると、二度目のインポートの時点でエラーが発生します。

 例えば、java.awt.Listとjava.util.Listを続けてインポートしようとすると以下のようなエラーが発生します。

js> importClass(java.util.List);
js> importClass(java.awt.List);
js: "", line 5: Cannot import "List" since a property by that name is already defined.
js: "", line 5: org.mozilla.javascript.EvaluatorException: Cannot import "List" since a property by that name is already defined. (#5)

 こうした理由から、importPackage()などを用いて、大量のクラスをトップレベルにインポートするのはあまり得策ではありません。インポートはソースコードの記述量を減らすことのできる強力な仕組みですが、「必要なクラスを必要な範囲においてのみ」インポートするのが理想だと言えます。

 こうした目的のために使用されるのが「JavaImporter」と言うクラスです。JavaImporterは、importPackage()やimportClass()と言ったメソッドを持ち、インポートしたクラスを自身のプロパティとして保持するクラスです。以下の例を見てください。

// JavaImporterの生成。インポートしたいパッケージを引数に取れる
var collections = JavaImporter(java.util);

// Commons CollectionsのAPIもインポート
collections.importPackage(org.apache.commons.collections);
collections.importPackage(org.apache.commons.collections.list);
collections.importPackage(org.apache.commons.collections.map);
collections.importPackage(org.apache.commons.collections.set);

// JavaImporterのプロパティとしてクラスにアクセスできる
var arrayList = new collections.ArrayList();
var fastMap = new collections.FastHashMap();

// with句を使えば、クラス名だけでのアクセスも可能
// with句はパフォーマンスに悪影響が出るので注意!
with (collections) {
     var multiMap = new MultiValueMap();
}
// 不要になったら、未定義にしてしまえばよい
collections = undefined;

パッケージやクラス定義を他のクラスに代入する

 また、わざわざこうしたRhino独自の関数を用いずとも、パッケージ名を省略する方法はあります。その方法とは、クラスやパッケージを他の(より記述の少なくて済む)変数に代入してしまえばよいのです。これは、Javaのパッケージ階層やクラスが全てJavaScriptオブジェクトで表されているからこそ、実現可能なテクニックです。

// java.util.HashMapの定義を、JavaHashMapという変数で参照できるようにする
var JavaHashMap = java.util.HashMap;
var hash = new JavaHashMap();

// java.utilパッケージをutilと言う変数で参照できるようにする
var util = java.util;
var arrayList = new util.ArrayList();

 こうした方法は、java.langパッケージのクラス名などを短縮して利用するのに適しています。java.langパッケージには、JavaScriptのコア言語で利用するクラス(String, Booleanなど)と名前が衝突するクラスが存在するため、単純にインポートできないためです。

// 以下のようにしてはいけない!JavaScriptのコアクラスと名前が衝突してしまう
//importPackage(java.lang);

// 以下のようにすれば、java.langパッケージ内のクラスを短く記述できる
var JString = java.lang.String;
var JBoolean = java.lang.Boolean;

var s = JString.valueOf(1);
...
このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]