5分で理解するProject Coin
はじめに
そろそろJDK7が登場する時が近づいてきたのでJavaプログラマならProject Coinを先取りして予習しておくべき時期になってました。Project CoinというのはThe Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 334となっているもので、Javaのコードをちょっとだけ簡単にしてくれるような文法の変化をもたらしてくれます。全部で5つありますので、一つ一つ見て行きましょう。
1. switch文でStringを (String in switch)
今はまだswitch文は整数値(char, byte, short, int)とそのラッパークラスしか使えないのはご存知のとおり。例えば以下のような文字列比較のif-else文を考えてみて下さい。
if ("A".equals(str)) { } else if ("B".equals(str)) { } else if ("C".equals(str)) { } else { }
ちとイケテナイですね。これがProject Coinになると以下のようにシンプルになります。
// switchでString! switch (str) { case "A": break; case "B": break; case "C": break; default: break; }
あらすっきり。地味に便利。
2. マルチキャッチ (Multi catch)
多くのメソッドが一つ以上のチェック例外を投げる可能性がある時、それらを全部捕捉してログに出してさらに投げ直すなんてことをしないといけません。
try { // Some EJB call } catch (NamingException e) { log.error(e); throw new RuntimeException(e); } catch (IOException e) { log.error(e); throw new RuntimeException(e); }
ちとイケテナイですね。これがProject Coinになると以下のようにシンプルになります。
try { // Some EJB call } catch (NamingException | IOException e) { // ←マルチキャッチ! log.error(e); throw new RuntimeException(e); }
パイプORで繋ぐんですね、これeの型はその都度変わるってことでいいんでしょうか?
3. リソース付きトライ (Try with resources)
プログラミングでよく犯しがちなミスとしてメモリリークがあります。これは例外発生時にクローズ処理などをし忘れてしまうことによる原因が多いです。なので以下の例のようにfinallyブロックできちんとクローズ処理を入れることを忘れないようにしないといけません。
Connection conn = null; try { conn = dataSource.getConnection(); // run query } catch (SQLException e) { } finally { if (conn != null) { try { conn.close(); } catch (Exception ignore) { } } }
Project CoinのJDK7では java.lang.AutoCloseable という新しいインタフェースが登場します。このインタフェースはclose() というメソッドだけを持っていて、InputStream, Reader, java.sql.Connection のようなクラスがこのインタフェースを実装しています。AutoCloseable なクラスはtry-with-resourceステートメントで使うことができます。コードがtryブロックを実行し終えると、close() メソッドが暗黙的にリソースを解放するために呼び出されます。上記で示したコードをJDK7スタイルにすると以下のような感じになります。
// try-with-resourceステートメント! try (Connection conn = dataSource.getConnection()) { // run query } catch (SQLException e) { }
for文の初期値のような感じでConnectionを宣言して使っているイメージなんですかね。自動でリソースを解放してくれるのは楽でいいですね。これはよいインタフェース。
4. 型推論 (Type inference)
総称型のインスタンス生成時の話です。Javaだとこんな感じになりますよね。
Map<String, List<String>> map = new HashMap<String, List<String>>();
うーん、冗長だなぁ。そこで、Project Coinでは右側だけすっきりさせられるようになりました*1。
Map<String, List<String>> map = new HashMap<>(); // ←右だけすっきり!
<>という形から通称「ダイヤモンド」と呼ばれているようです。
ね?すっきりしたでしょ?え?Scalaとかに比べると微妙だって?それは言わないお約束:-)
ちなみにScalaだと
val map = Map[String, List[String]]()
5. 2進数リテラルと数値のアンダースコア区切り (Binary integral literals and underscores in numeric literals)
Project CoinのJDK7からは2進数用のリテラルが使えるようになりました。ちょうど16進数を表すのに頭に "0x" を付ける感じで、2進数の場合は頭に "0b" を付けます。さらに、数値リテラル中に区切り文字としてアンダースコアを入れられるようになりました。
1234_5678 1_2_3_4__5_6_7_8L // アンダースコアはいくつあってもOKのようです 0b0001_0010_0100_1000 3.141_592_653_589_793d 0x1.ffff_ffff_ffff_fP1_023 // Double.MAX_VALUE
また、以下のような感じに、アンダースコアの位置が悪いと使えないようです。
_1234 0x_1234 1234_ 0x1.0_p_-1022
ちなみにRubyの数値リテラルでも出来てますね。やっとJavaでもできるようになったということで。
修正履歴
- 2011-04-20 @frooprogrammerさんにScalaのサンプルをもっと簡潔に書けるよとのご指摘を頂いたのでそれを反映。
- 2011-04-24 「マルチキャッチ」について@nobeansさんに教えてもらった内容(これとこれ)を反映。
- 2011-04-24 「2進数リテラルと数値のアンダースコア区切り」を追加。
参照
The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 334
Java in the Box Annex: Project Coin (2011-04-24追加)
GroovyにおけるProject Coin相当拡張について - Grな日々(uehajの日記) (2011-04-24追加)
Java 7における5つ(かそこいら)の変更点確定版 - Grな日々(uehajの日記) (2011-04-24追加)
*1:右なんだ…宣言する型だけはしっかり書かせるわけですね。