JavaFX 1.0 とJavaのGeneric Class

JavaFXJavaのオブジェクトを呼び出すことができる.たとえばなにかを標準出力にプリントする際には,

import java.lang.System;

System.out.println("Hello");

のように書く.ただし,Javaと違ってjava.lang.* が自動的にインポートされたりしないので,明示的にimport する必要がある.

配列

配列もちゃんと使える.

public class Callee {
    static String [] getArray(){
        return new String[] {
          "aaa", "bbb", "ccc"
        };
    }
}

こんなJavaのメソッドをJavaFXから呼び出すとちゃんと文字列の配列になってくれる.

var ary:String[] = Callee.getArray();
for (s:String in ary) {
    System.out.println(s);
}

一見当たり前のようにも見えるが,実際にはJavaの配列とJavaFXの配列は全然別の実装になっているはずなので,システムががんばって変換してくれているのだろう.すごい.

Collection

ところが,Collection まわりが使いにくい.問題はJavaFXGenericsに対応していないこと。

public class Callee {
    static List<String> getList(){
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        return list;
    }
}

このメソッドをJavaFXで呼び出す.本当は

var list:List<String> = Callee.getList();

とやりたいところだが,

Java generic type declarations are not currently supported.

となって,コンパイルできない.currentlyということなのでそのうちサポートされるのだろうけど.

genericsを使わなければコンパイルはできるのだが,今度は中身のアクセスが難しい.

var list:List = Callee.getList();
var v1:String = list.get(0);

とやると,listの中身はObject型なのにStringの変数に代入しようとしているということで怒られる.

Main.fx:24: incompatible types
found   : Object
required: String

まあ,これはgenericsを使わない場合のJavaでも同じ.仕方が無いのでキャストしようとすると、なんか知らんがキャストできない!

var list:List = Callee.getList();
var v1:String = (String)(list.get(0));
Main.fx:24: cannot find symbol
symbol  : variable String

エラーメッセージから見ると,そもそもキャストという構文が無いんじゃないかという感じ.

Webで検索すると,0.7時代のサンプルではがんがんキャストが使われているので,どうもこれも1.0になったときに変わったらしい.
#というか,バグなんじゃないかという気もするが...

String型でない変数に代入することはできる.

var list:List = Callee.getList();
var v1 = list.get(0);

が,これだと,String型固有のメソッドはもちろん使えない.

所感

単純な実装上の手違いだと思いたい.このままではCollectionクラスがまともに利用できない.generics に対応してくれれば当面は困らないかもしれないが..