Tcl処理系でJava言語のコードを実行するには

 超基本から行きましょう。Tcl Blendをインストールした環境で、

package require java
set obj [java::new SampleApplet]
$obj init
$obj start
上のようなTclコードを書けば、
SampleApplet obj = new SampleApplet();
obj.init();
obj.start();
このようなJavaコードと同じように実行してもらえます。 java::new コマンドで指定されたクラスは必要に応じて、 Javaの純正処理系がやるのと同じような方法でクラスファイルを探し、Java仮想機械にロードしてきます。 詳しくはJava言語のマニュアル、Java処理系のマニュアル、Tcl/Javaのマニュアルをご覧ください。
 それはそうと、上のobjで思い出しましたが、 Javaクラスのインスタンスのことは、Tcl Blendの文書ではしばしば、 Javaオブジェクトと呼ばれます。 JavaオブジェクトというのはJava世界のオブジェクトを Tcl Blend で扱うときに使う言葉で、そのID(java::newコマンドが返す値)のことは、 オブジェクトハンドルと呼ばれています。


Tcl言語でJavaのクラスを操作しよう

 Tcl Blendを使うと、JavaのクラスをTcl言語で操作することができます。 ここではJava標準のクラスのひとつ、java.util.StringTokenizer を使ってみます。Tclのsplitコマンドの方が便利なのは便利ですが、 ここではあくまでロードして使ってみようというわけで。

package require java
set string {This is the joy in the world.}
set a [java::new java.util.StringTokenizer $string]
while {[$a hasMoreTokens] != 0} {
    set token [$a nextToken]; puts $token
}

これを実行させると、
This
is
the
joy
in
the
world.
と1単語ずつ切り出されます。
 ポイントは、インスタンスを生成するjava::newコマンドと、 その戻り値(オブジェクトハンドル) をコマンドとして、インスタンスの同名のメソッドを最初の引数として指定して呼び出せることです。 java::newコマンドで指定するクラスは、完全修飾(fully qualified)で指定しています。 つまりこの場合は「java.util.StringTokenizer」となります。 が、java::importコマンドを使うと、Javaのimport文のように、クラス名だけで指定することができるようになります。 例えば、

set a [java::new java.util.StringTokenizer $string]

は、

java::import java.util.StringTokenizer
set a [java::new StringTokenizer $string]

とも書けます。
それで話は元に戻って、 その後ろ以降の引数はそのままそのクラスの適合するコンストラクタへの引数になります。

 ところで上のTclスクリプトを本来のJava言語で書いた場合、このようになります。

String string = "This is the joy in the world.";
StringTokenizer a = new StringTokenizer(string);
while(a.hasMoreTokens()) {
    String token = a.nextToken();
    System.out.println(token);
}

●クラスメソッドはどうやって呼び出すんだ?
インスタンス変数はどうやってアクセスするんだ?
 ぐおー、なんだかわからない世界になってきましたねえ。 これらはそれぞれ java::call、java::field というコマンドでそのまま使えます。例えば、

public class Sample {

  public int instance_variable;

  public static final int multiply(int v){
    return v * instance_variable;
  }
  // ...
}

 こんな意味不明のクラスSampleがあったとして、

set r [java::call Sample multiply $v]
(Sampleの代わりにSampleのインスタンスの名前でもOK)

こんな感じで使います。また、

set instance [java::new Sample]
# ......
set r [java::field $instance instance_variable]

これで$rにはインスタンス変数instance_variableの値が得られます。逆に

set instance [java::new Sample]
# ......
java::field $instance instance_variable $r

とすると$rの値がインスタンス変数instance_variableに代入されます。

拡張レビュー分室 top
(first uploaded 1998/12/15 last updated 2005/11/06, KOUKEN HEIJIMA - MISUMI URANO)