読者です 読者をやめる 読者になる 読者になる

No Programming, No Life

新しいNPNLです。http://d.hatena.ne.jp/fumokmm/ から引っ越してきました。

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の型はその都度変わるってことでいいんでしょうか?

2011-04-24追記

マルチキャッチ構文で書いた場合はコンパイルするとマルチキャッチの部分を展開して、同じ例外処理を行なうコードに書き換えているようです。つまり最初のJavaコードのように書いたのと同じ効果が得られるというわけです。
また、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でもできるようになったということで。

修正履歴

*1:右なんだ…宣言する型だけはしっかり書かせるわけですね。