エンターテイメント!!

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

Java14事前調査 JEP 359: Records (Preview)

環境

$ java -version
openjdk version "14-ea" 2020-03-17
OpenJDK Runtime Environment (build 14-ea+34-1452)
OpenJDK 64-Bit Server VM (build 14-ea+34-1452, mixed mode, sharing)

eary accessのページからダウンロードしたやつだと、recordsがまだ入ってないやつっぽい。。。
recordsを試すなら、sdkmanから最新のバージョンを落としてくるのが良さげ。

JDK 14 Release Candidate Builds

それに気づくのにだいぶ遅れて、少し前のバージョンでビルドが通らずに四苦八苦してた。。。

$ VER
Microsoft Windows [Version 10.0.18362.592]

JDK14

JDK 14

JEP 359: Records (Preview)

JEP 359: Records (Preview)

概要(超要約)

データ保持用のクラス定義方法を追加
かなり乱暴に言うと、構造体みたいなものを追加した感じ。

テストコード

public class JEP359 {

  public static void main(String[] args) {
    Range record = new Range(3, 10);
    System.out.println(record);
  }

}

record Range(int lo, int hi) {
  public Range {
    if (lo > hi)  /* referring here to the implicit constructor parameters */
      throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi));
  }
}

JEP359にあるサンプルを流用。

実行

$ javac --enable-preview -source 14 JEP359.java 
$ java --enable-preview JEP359
Range[lo=3, hi=10]

想定通りの結果。

追加補足

public class JEP359 {

  public static void main(String[] args) {
    Range record = new Range(3, 10);
    System.out.println(record);
    System.out.println(record.lo());
  }
}

生成されたインスタンスの値を取得したい場合、record.lo()のようにアクセスする。
個人的には、プロパティ的な立ち位置なので、record.loでアクセスしたい。。。

IllegalArgumentExceptionを起こすテストコード

public class JEP359 {

  public static void main(String[] args) {
    Range record = new Range(3, 1);
    System.out.println(record);
  }
}

record Range(int lo, int hi) {
  public Range {
    if (lo > hi)  /* referring here to the implicit constructor parameters */
      throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi));
  }
}

実行

$ javac --enable-preview -source 14 JEP359.java 
$ java --enable-preview JEP359
Exception in thread "main" java.lang.IllegalArgumentException: (3,1)
        at Range.<init>(JEP359.java:15)
        at JEP359.main(JEP359.java:5)

補足

  public Range {
    if (lo > hi)  /* referring here to the implicit constructor parameters */
      throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi));
  }

上記部分がコンストラクタのような動きをする。
これがあることで、不安定状態(値の整合性が取れてない)のインスタンスが作れないようにできる。

感想

変数へのアクセス方法が、個人的に不満
役割が明確なら、メソッドアクセスじゃなく、変数アクセスっぽいほうが好き。

無駄にコード量が増えるのを抑制できるのは、評価したい。