Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2024/09/12 JJUG ナイトセミナー: JEP 482 Flexible Const...

2024/09/12 JJUG ナイトセミナー: JEP 482 Flexible Constructor Bodies (Second Preview)

汐月麻理佳

September 12, 2024
Tweet

More Decks by 汐月麻理佳

Other Decks in Programming

Transcript

  1. 目的 Javaのコンストラクタに関する従来の制約を緩和し、より柔軟で表現力豊かなコード が書けるようにすること JEP447 Flexible Constructor Bodies (Second Preview) を名前変更して、第2プレビ

    ューとして機能追加 : Java22でリリース済み JEP482の変更点 コンストラクタ本体が、コンストラクタを明示的に呼び出す前に、同じクラス内のフ ィールドを初期化できるようにする。 3
  2. sample class Base { Base(int x) { System.out.println("Base constructor: "

    + x); } } class Derived extends Base { int y; Derived(int x, int y) { System.out.println("Setting y"); super(x); // superの前にインスタンスに関与しないステートメントを配置 this.y = y; } } 5
  3. sample class Base { Base(int x) { System.out.println("Base constructor: "

    + x); } } class Derived extends Base { int y; Derived(int x, int y) { this.y = y; // フィールドの初期化をsuperの前に配置可能 System.out.println("Derived constructor: " + y); super(x); } } 7
  4. 利用例 1 : スーパークラスのコンストラクタ引数の検証 < Beforeパターン1:初期化後に検証する> public class Sub extends

    Super { public Sub(long value) { super(value); // 制約による親クラスの呼び出し if (value <= 0) throw new IllegalArgumentException("not allowed value"); } } 8
  5. < Beforeパターン2:スーパークラスのコンストラクタ呼び出し前に検証する> public class Sub extends Super { public Sub(long

    value) { super(verifyValue(value)); } private static long verifyValue(long value) { if (value <= 0) throw new IllegalArgumentException("not allowed value"); return value; } } 9
  6. <適用後> public class Sub extends Super { public Sub(long value)

    { if (value <= 0) throw new IllegalArgumentException("not allowed value"); super(value); } } 10
  7. 利用例2 : スーパークラスのコンストラクタ引数の準備 <適用前> public class Sub extends Super {

    private static String format(int zipCode) { return zipCode.substring(0, 3) + "-" + zipCodee.substring(3); } public Sub(int zipCode) { super(format(zipCode));   } } <適用後> public class Sub extends Super { public Sub(int zipCode) { String code = zipCode.substring(0, 3) + "-" + zipCodee.substring(3); super(code);   } } 11
  8. 利用例 3 : スーパークラスのコンストラクタ引数の共有 <適用前> public class Super { public

    Super(C x, C y) { ... } } public class Sub extends Super { private Sub(C x) { super(x, x); } public Sub(int i) { this(new C(i)); } // 親クラスの初期化に必要な準備 } <適用後> public class Sub extends Super { public Sub(int i) { var x = new C(i); super(x, x); } } 12
  9. 利用例 4 : フィールドへの早期割り当て <適用前> class Super { // override側が呼ばれるが、初期化されていないので、0になる。

    Super() { overriddenMethod(); } void overriddenMethod() { System.out.println("hello"); } } class Sub extends Super { final int x; Sub(int x) { /* super(); */ // 暗黙的呼び出し this.x = x; } @Override void overriddenMethod() { System.out.println(x); } } 13
  10. <適用後> class Super { // 初期化を先に実行しているのでSub(1)の場合、1が印字される。 Super() { overriddenMethod(); }

    void overriddenMethod() { System.out.println("hello"); } } class Sub extends Super { final int x; Sub(int x) { this.x = x; super(); } @Override void overriddenMethod() { System.out.println(x); } } 14
  11. 未初期化のフィールドアクセスの禁止 class A { int i; A() { System.out.print(this); //

    Error var x = this.i; // Error this.hashCode(); // Error var x = i; // Error hashCode(); // Error super(); } void m(); } class B extends A { B() { var x = super.i; // Error super.m(); // Error super(); } } 18