JDK 7の新機能 Peoject Coin編(その1)

先日、JDK 7の開発者プレビューと、JDK 7に対応したNetBeans 7.0 Beta 2がそれぞれリリースされました。せっかくなのでJDK 7の新機能をおさらいしつつ、実際にNetBeansを使って試してみたいと思います*1

JDK 7の新機能についてはこのページに一覧がまとめられています。まずは最も身近とも言える「Project Coin」からいってみましょう。Project Coinは、個別に仕様化するほどではない細かな文法の変更や追加などの実装を進めたプロジェクトです。JCPでは「JSR 334: Small language enhancements」として登録されています(現在、ドキュメントがダウンロードできます)。現在のところ、JSR 334にはJava SE 7に搭載する新機能として次のものが挙げられており、いずれもJDK 7ではすでに実装が完了しています。

  • Stringによるswitch文
  • 2進数リテラルとアンダースコア付き数値リテラル
  • 複数例外のキャッチおよび例外の安全な再スロー
  • 型推論によるジェネリクスのオブジェクト生成(ダイアモンド)
  • リソース付きのtry-catch
  • 可変長引数を使うメソッド呼び出しの警告を抑制(@SafeVarargsアノテーション

Stringによるswitch文

まずStringを使用したswicth文についてですが、これはswitchの条件に文字列リテラルが使えるようになったということです。次のような感じです。

  static void testStringSwitch(String str) {
    switch (str) {
      case "hoge": 
        System.out.println("ほげほげ");
        break;
      case "piyo": 
        System.out.println("ぴよぴよ");
        break;
      default: 
        System.out.println("デフォルト");
        break;
    }
  }

strにnullを渡すをNullPoinerExceptionがスローされます。これはIntegerなどの場合と同様ですね。
switch文のこの拡張は、現時点ではJVMには影響を与えません(将来サポートされる可能性はあります)。JVMではswitchを扱う命令としてlookupswitchとtableswitchがあるわけですが、これらは依然として文字列リテラルをサポートしてないということです。ではどうやって比較しているのかというと、コンパイラは文字列をバイトコードシーケンスに変換し、それを比較に利用しているとのことです*2

2進数リテラル

Javaでは、"0x"を数値の前に付けて16進数の数値を表すことができます。JDK 7では、同じような方法で2進数の数値を表すこともできるようになりました。2進数は、数値の前に"0b"または"0B"を付けて表現します。次のような感じです。

    int binary = 0b011001;
    System.out.println(binary);
    int binary2 = 0B110100;
    System.out.println(binary2);

出力は以下のように普通の10進数形式になります。

25
52

次のような表記はできません。これは0xの場合と同じです。

    int binary3 = 0b12345;  // コンパイルエラー

アンダースコア付き数値リテラル

数値リテラルについてはもうひとつ変更があります。数値の途中に「1_234_567」のようにアンダースコア("_")を入れられるようになったことです。これは内部的には普通に「1234567」として扱われます。「1,23,567」のような区切り文字付きの数値と同じようなものと考えていいでしょう。この変更はコードの可読性を上げるために採用されました。アンダースコアは連続して付けることもできますが、数値の先頭や最後に付けることはできません。

    int withUnderscore = 123_456_789;
    System.out.println(withUnderscore);
    int withUnderscore2 = 9_8_7_6_5;
    System.out.println(withUnderscore2);
    int withUnderscore3 = 123__456;
    System.out.println(withUnderscore3);

出力結果は次のようになります。

123456789
98765
123456

次のような書き方はコンパイルエラーになります。

    int withUnderscore4 = _123456;  // コンパイルエラー
    int withUnderscore5 = 123456_;  // コンパイルエラー

通常の数値リテラルと同じなので、次のようなこともできます。

    for (int i = 0; i < 1_00; i++) { ... }

2進数リテラルや16進数リテラルなどの中で使うこともできますが、これも先頭や末尾に付けるのはダメです。

    int binary4 = 0b0_110_01;
    int hex = 0x123_abc;
    //int binary5 = 0b_011001;  // コンパイルエラー

NetBeansでの数値リテラルの自動変換

数値リテラルに関連して、NetBeans 7.0には数値の表記を自動で変換してくれる機能が追加されました。数値の部分にカーソルがある場合に、次のようにコードヒントが出て、任意の基数に自動で変換してくれます。自分で計算する手間が省けるので地味に便利です。

続きは次回に。

*1:JDK 7のインストールについてはこのエントリを、NetBeans 7.0のインストールについてはこのエントリをそれぞれ参照してください

*2:このエントリも参照してください