エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

Java13リリース前の予習

書こうと思ったきっかけ

そろそろリリースが近づいて来たので、まとめようと思い一念発起した。
サイト見る限り、最終リリース候補が出てるようなので、もう、大きな変更はないだろうから、キャッチアップしても大丈夫だろうという考えもある。

各種サイトへのリンク

https://openjdk.java.net/projects/jdk/13/

JDK 13 Early-Access Builds

JEP

  • 350: Dynamic CDS Archives
  • 351: ZGC: Uncommit Unused Memory
  • 353: Reimplement the Legacy Socket API
  • 354: Switch Expressions (Preview)
  • 355: Text Blocks (Preview)

ざっくり読んだ感じ、開発者に影響がありそうなのは、JEP 354/JEP 355

JEP 353も影響ありそうかと思ったけど、内部の実装の変更のようなので、調査対象から外した。
Google翻訳でやってるから、微妙に違うところがあるかも。。。
あと、見てて思ったが、JavaでSocketAPIを直に見るのは、学生のとき以来だなって思った。

354: Switch Expressions (Preview)

簡単に言うと、switchの結果を変数に入れられるようになった。

テストコード

下記の通り、テストコードを作成
java12のやつを流用して作った。

import java.util.Calendar;
import static java.util.Calendar.*;

public class jep354sample {
  public static void main(String[] args) {
    int day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
    int numLetters = switch (day) {
      case MONDAY, FRIDAY, SUNDAY -> 6;
      case TUESDAY                -> 7;
      case THURSDAY, SATURDAY     -> 8;
      case WEDNESDAY              -> 9;
      default -> 0;
    };
    
    System.out.println("numLetters:" + numLetters);
  }
}

実行

最初、defaultがない状態でコンパイルしようとしたら、下記の通り、コンパイルエラーになった。

$ javac --enable-preview --release 13 jep354sample.java 
jep354sample.java:7: エラー: switch式がすべての可能な入力値をカバーしていません
    int numLetters = switch (day) {
                     ^
注意:jep354sample.javaはプレビュー言語機能を使用します。
注意:詳細は、-Xlint:previewオプションを指定して再コンパイルしてください。
エラー1個

網羅されてないとエラーになるようになったんだな。。。
それとも、前から?
Java12のときは、エラーにならなかった気がするが、気のせいかな?

本題とはそれるので、とりあえず、コンパイル&実行

$ javac --enable-preview --release 13 jep354sample.java 
$ java --enable-preview jep354sample
numLetters:8

土曜日なので、SATURDAYだから、8で正解。
どうでもいい話だが、SATURDAYは、一週間が終わったから「去ったデー」って習った。

注目スべきは、switchの戻り値があるところだろう。
これで、ケースに応じて結果を返せるようになった。
個人的には、defualtの挙動の方が驚いた。。。

swiftの画面遷移とかで使うswitchの使い方に近いことができるのではないかと思う。

yield

yieldっていう結果返すワードが追加されたので、試す。

テストコード

public class Jep354YieldSample {
  public static void main(String[] args) {
    String day = "xxx";
    int j = switch (day) {
        case "MONDAY"  -> 0;
        case "TUESDAY" -> 1;
        default      -> {
            int k = day.toString().length();
            System.out.println("default day:" + day);
            int result = f(k);
            yield result;
        }
    };
    
    System.out.println("j:" + j);
  }
  
  private static int f(int k) {
    return k + 10000;
  }
}

実行

実行したら、下記の通り。

$ javac --enable-preview --release 13 Jep354YieldSample.java 
$ java --enable-preview Jep354YieldSample
default day:xxx
j:10003

caseの中で計算が必要なときに使うのだろうけど、必要なのか疑問に感じてしまう。。。
とりあえず、新しい動きなので、覚えておいて損はないだろう。

355: Text Blocks (Preview)

開発者が定義した通りの文字列を定義できる。 エスケープ処理が入るので、開発者は、\nとかを気にしなくていい

テストコード

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Jep355Sample {
  public static void main(String[] args) throws Exception {
    String html = """
              <html>
                  <body>
                      <p>Hello, Saga!!</p>
                  </body>
              </html>
              """;

    System.out.println("== html ==");
    System.out.println(html);
    System.out.println("==========");

    String query = """
               SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
               WHERE `CITY` = 'INDIANAPOLIS'
               ORDER BY `EMP_ID`, `LAST_NAME`;
               """;

    System.out.println("== sql ==");
    System.out.println(query);
    System.out.println("=========");

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
    Object obj = engine.eval("""
                            function hello() {
                                print('"Hello, Saga!!"');
                            }
                            
                            hello();
                            """);
  }
}

やってるのは、HTMLとSQLの表示、JSの実行。

実行

$ javac --enable-preview --release 13 Jep355Sample.java 
$ java --enable-preview Jep355Sample
== html ==
<html>
    <body>
        <p>Hello, Saga!!</p>
    </body>
</html>

==========
== sql ==
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;

=========
Warning: Nashorn engine is planned to be removed from a future JDK release
"Hello, Saga!!"

エスケープ文字列入れてないのに、ちゃんと改行されて、きれいにHTMLとSQLが出力される。
jsも、エスケープ処理なくても、きちんと実行できて"Hello, Saga!!"が出力される。

簡単なDBアクセスでSQL発行するサンプルを作りたいとか、簡単にできそう。
できれば、文字列の代入もあるといいかなと思う。
いちいちプラスで連結するのは、面倒。
Swiftみたいに、\()で代入できると楽なんだが、対応予定はあるのかな?

感想

355: Text Blocks がとても気になる。
文字列操作がもどかしいことがよくあるので、これからも継続的に改善があると嬉しい。

スケジュール通りに進んでいるようなので、Java13も予定通りリリースされると思う。