J2SE 1.5 (Tiger) download から J2SE 1.5 をダウンロードしてインストールしよう。主要な変更点を試すのに忘れてはいけないのは、javac コマンドでコンパイルするときに -source 1.5 を追加することだけだ。
Nutshellで紹介されているのは、次の内容だ。
・Metadata
・Generic Types
・Autoboxing and Auto-unboxing of Primitive Types
・Enhanced for loop
・Enumerated types
・Static Import
・Formatted Output
・Formatted Input
・Varargs
・Concurrency Utilities
・rmic — the rmi Compiler
・Concurrency Utilities
・Scalability and Performance
・Monitoring and Manageability
・New JVM profiling API (JSR-163)
・Improved Diagnostic Ability
・Desktop Client
その他
・Core XML Support
・Supplementary Character Support
・JDBC RowSets
さっそく、例をみてみよう。
Generic Types
まずは、Generic Types について見てみよう。従来のCollections API では、集合の要素はすべてObject型であることを前提として設計されていたので、Collectionの要素に対する型チェックをコンパイラは実質的にできなかった。型チェックやキャストによる調整は、プログラマの仕事になっていた。これをコンパイラにやらせることができるように言語が拡張された。いわゆるC++でいうところのテンプレート機能だ。
public class GenericTest {
public static void main(String[] args) {
// version 1.4 code
ArrayList list = new ArrayList();
list.add(0, new Integer(12));
int total = ((Integer)list.get(0)).intValue();
System.out.println(“list.get(0) :”+total);
// version 1.5 code
ArrayList
genericList.add(0, new Integer(20));
total = genericList.get(0).intValue(); // キャストの必要ない
System.out.println(“genericList.get(0):”+total);
}
}
コンパイルするときには、version 1.4 の方では warning が出力される。どんなメッセージが出力されるかも見るために、詳細表示できるオプションを指定してコンパイルしてみよう。
実行するには、普通に java コマンドを使えばいい。ちなみに、Java2 1.4 では Generic type を使ったプログラムを実行させることはできないようだ。Beta1 では、コンパイル時に -source 1.5 を指定すると、-target オプションで 1.4 を指定することができない。
list.get(0) :12
genericList.get(0):20
Autoboxing and Auto-unboxing of Primitive Types
Generic Types のところで出てきたが、これまではプリミティブ型の変数へラッパークラスのインスタンスを直接代入することはできなかったし、参照型変数へプリミティブ型の値を代入することはできなかった。genericList.add(0, new Integer(20)); や, int total = genericList.get(0).intValue(); は良い例だ。1.5からは、これらの代入が簡単にできるようになった。
public class AutoboxingTest {
public static void main(String[] args) {
// version 1.5 code
ArrayList
genericList.add(0, 20); // int から Integerへは自動変換
int total = genericList.get(0); // Integerからintへは自動変換
System.out.println(“genericList.get(0):”+total);
}
}
実行は簡単。この記述ができると、コード自体はかなりすっきりする。(これで、初学者にはプリミティブ型を教えなくてもよくなるのかな。そうするといろいろと初期の説明が統一してできるようになるので嬉しいのだけれど。それとも、逆に難しく感じるようになるだろうか)
genericList.get(0):20
Enumerated types
反覆処理をするときに、java.util.Iterator を使っていた場合が結構あるだろうが、これは決まりきった処理になるので、もっと簡単に使えるようにするために、簡易記述が提供されるようになった。
import java.util.Iterator;
public class EnhancedForLoopTest {
public static void main(String[] args) {
ArrayList
list.add(20);
list.add(40);
list.add(60);
// Iterator
for (Iterator i = list.iterator(); i.hasNext();) {
Integer value = (Integer)i.next();
System.out.println(value);
}
// Enhanced for loop
// 取扱う集合は list, 要素は Integer型で iで参照
for (Integer i : list) {
System.out.println(i);
}
}
}
これも実行は簡単。見慣れるまでちょっと違和感があるかもしれないが、どんな集合に対して反覆処理をしているのか理解するのに必要な情報が一目でわかるので、積極的に使って行くべきだろう。
20
40
60
20
40
60
Generic Typesはとてもうれしい機能ですね。Java2 1.5を安心して使える日が待ち遠しいです。
タイプセーフなコレクションは、C#にも欲しい。