第2回は、Java SE 7による変更点を見ていきます。今までは、わずらわしさを感じていたJavaプログラムがすっきり記述できて、開発がグッと楽になるでしょう。

 プログラミング言語のJavaは、多くの開発者の意見を取り入れて進化を続けています。5年ぶりのバージョンアップになったJava SE 7では、簡易的な記法を取り入れると共に、次期バージョンであるJava SE 8に向けた機能を実装しました。当初予定されていた目玉となる機能のProject Lambdaが先送りになってしまったので、それがないJava SE 7は“小粒なバージョンアップ”という印象を持っている人も多いのではないでしょうか。

 しかし、そんなことはありません。Java SE 7も多岐に渡って機能の追加や拡充が図られています。

Java SE 7の概要

表1●Java SE 7の主な機能
表1●Java SE 7の主な機能
表2●Project Coinにおける変更点
表2●Project Coinにおける変更点

 Java SE 7の機能を三つに分けて説明します(表1)。一つ目がかゆいところに手が届く機能、二つ目がJava SE 8の基盤となる機能、三つ目がその他の機能です。

 かゆいところに手が届く機能というのは、今までのJavaでは実装できなかった部分や、Javaで書くのはどうしてもコードが冗長になってしまった部分をすっきり記述できるようにする機能です。Java SE 8の基盤となる機能は、Java SE 8で導入する機能のために必要な機能です。

 今回は、かゆいところに手が届く機能として「Project Coin」と「NIO.2」について解説します。Java SE 8の基盤としての「Fork/Join Framework」と「InvokeDynamic」は次回に説明します。

 Project Coinは、使いにくかったJavaの文法を変更するプロジェクトです。ただし、インパクトの大きい変更は対象外になります。つまり、小さい言語仕様の変更を行うのがProject Coinです。英語でCoinはコイン、つまり小銭のことですね小銭を他の言葉で言い換えると「Small Changes」です。このSmall Changesを普通に訳すと小さい変更です。つまり、Project Coinのプロジェクト名はダジャレで決まっているのです*1

 Project Coinでは、記法の変更を一般から公募しました。70件近くの提案があったのですが、厳選なる選考が行われて、8件の変更が採用されました。表2に採択された項目を示します*2。ここでは、言語仕様の変更の中からジェネリクスの省略記法とリソースの自動クローズについて詳しく説明します。

ジェネリクスの省略記法

 ジェネリクスはJ2SE 5.0から導入されたもので、「型」を変数にした「型変数」というものを取り扱います。既にジェネリクスは、コレクションAPIをはじめ、様々なAPIやフレームワークに使用されていますね。

 ジェネリクスを使うと、キャストを使用しなくても済むなどプログラムの安全性を高められます。例えば、文字列のListオブジェクトを生成するには、図1のように記述します。変数の定義にジェネリクスを記述するのは仕方のないこととして、インスタンス生成時のnewにも同じジェネリクスを書くのは何とも冗長な感じがします。

図1●Java SE 7ではダイヤモンド演算子によって記述を楽に
図1●Java SE 7ではダイヤモンド演算子によって記述を楽に
[画像のクリックで拡大表示]

 そこで、少しでも記法を楽にしようと、Project Coinではインスタンス生成時にジェネリクスを省略して記述できるようになりました。ただし、ジェネリクスであることを示すために、図1の右側のように< >だけを記述します。< >の形がダイヤモンドに似ていることから、これをダイヤモンド演算子と呼びます。

リスト1●複雑なジェネリクスでも記述可能
リスト1●複雑なジェネリクスでも記述可能
[画像のクリックで拡大表示]
リスト2●ダイヤモンド演算子が失敗するパターン
リスト2●ダイヤモンド演算子が失敗するパターン
[画像のクリックで拡大表示]

 ジェネリクスを省略して記述した場合は、Javaのコンパイラが型を推論して適切な型を補完してくれます。ジェネリクスが入れ子になった場合でも、型推論が可能です。例えば、リスト1のように複雑なジェネリクスでもダイヤモンド演算子を利用して記述できます。

 ただし、注意点もあります。ダイヤモンド演算子を使うことでジェネリクスを簡単に記述できますが、ダイヤモンド演算子は万能ではありません。例えばリスト1で示した式の後に、変数listに値を代入する場合を考えてみましょう(リスト2)。この式は、コンパイルエラーになってしまいます。メソッドの引数にダイヤモンド演算子は使用できません。このような制限については、Java SE 8で改善されることが決まっています。