Slide 1

Slide 1 text

Chihiro Ito Java Platform Advocate, Red Hat. Java Language Future 1

Slide 2

Slide 2 text

自己紹介 伊藤ちひろ (Chihiro Ito) 日本Javaユーザグループ 幹事 OpenJDK コミッタ Quarkus Contributor Java Platform Advocate @ Red Hat 自己紹介 Profile @chiroito

Slide 3

Slide 3 text

3 本資料は Oracle 社のJava Language Architect である Brian Goetz 氏が Devoxx Belgium で講演 された Java Language Update を同氏の許可を 得て翻訳しています。

Slide 4

Slide 4 text

4 本資料について Java Language Update の未来の部分を抜粋 元動画 ● 本資料の動画の最初からのリンク ● 本資料の対象範囲からはじまるリンク P. XX もとの資料のページ番号

Slide 5

Slide 5 text

5 Reconstruction expressions (作業中) ● Record は不変のデータ保持者であり、"getter "を内蔵する ● 不変オブジェクトの "setter "に相当するものは何か? ○ setterは、可変オブジェクトに対して「このプロパティを分離して変更」を意味する ○ 不変オブジェクトに相当するものは、既存のオブジェクトをコピーする。 しかし、指定された要素には異なる値が設定される。 ■ 「Point p のコピーだが、x 要素はゼロに設定される」 ● Record の “wither "のメソッドを書いてもらうこともできる。 ● しかし、まずい! ○ せっかくエラーになりやすい定型文をなくしたのに、また増やすのか? record Point(int x, inty) { Point withX(int newX) { return new Point(newX, y); } Point withY(int newY) { return new Point(x, newY); } } P. 35

Slide 6

Slide 6 text

6 Reconstruction expressions (作業中) ● 再構築式は、Record の値と、Record の要素を操作する一連の手続きを取り、新しいRecordに評価する。 ● これはどういう意味か? ○ Record の各要素は変更可能なローカル変数に変更され、そのロカール変数の終了値がRecordのコン ストラクタに戻されて新しいRecordが生成される。 ○ これはおおまかに次のようになる。 ○ 手続きは、代入だけでなく、どんなJavaの手続きでも構わない。 P. 36 Point p = … Point p0 = p with { x = 0; } Point p0 = switch (p) { case Point(var x, var y) -> { x = 0; yield new Point(x,y); } }

Slide 7

Slide 7 text

7 Reconstruction expressions (作業中) ● Record のメソッドを実装するために再構成式を使用できる。 ● 再構成式はネストできる。 P.37 record Complex(double re, double im) { Complex conjugate() { return this with { im = -im } } } record Point(int x,int y) {} record Circle(Point center, int radius) {} Circle c = aCircle with { center = center with { x = 0; } }

Slide 8

Slide 8 text

8 Deconstruction patterns for classes (作業中) ● Record は、"Record パターン "によってデコンストラクタをサポートする。 ○ 状態記述から導出できるため、私たちは"無償 "でこれを手に入れられる。 ● 任意のクラスでもデコンストラクタ・パターンを得られるのか? ○ はい。ただし、コンストラクタを逆にしたような「デコンストラクタ」を書く必要がある P. 38 Class Person { final String first, last; … public Person(String first, String last) { this.first = first; this.last = last; } public deconstructor Person(String first, String last) { first = this.first; last = this.last; } }

Slide 9

Slide 9 text

9 Deconstruction patterns for classes (作業中) ● そうすれば、Recordと同じようにクラスをデコンストラクトできるだろう。 ○ レコード・パターンはデコンストラクション・パターンの特殊なケースに過ぎない。 ● さらに進んで:クラスのデコンストラクタができるようになると、 Record と同様にクラスの再構築式もできる。 ○ 暗黙的に不変であるバリュー・タイプについても、再構成は有用である。 P. 39 if (x instance of Person(String first, String last)) { … }

Slide 10

Slide 10 text

10 Statements before super() (JEP 447, もうすぐ) ● 現在、コンストラクタの委譲 (this(...) /super(...)) はコンストラクタの最初の手続きでなければならないとい う制約がある。 ○ オブジェクトにアクセスする前に、親クラスが初期化されていることを保証するための、 意図的な制限である。 ● しかし、これは不必要な制限であり、いくつかの有用な慣習的な使い方を除外している。 ○ 引数の検証、親クラスのコンストラクタへの計算された引数。 ○ そこで、コンストラクタの委譲の前例として、this にアクセスしない手続きを許可する。 public class PositiveBigInteger extends BigInteger { public PositiveBigInteger(long value) { if (value < 0) throw new IllegalArgumentException(value); super(value); } } P. 40

Slide 11

Slide 11 text

11 Primitive type patterns (作業中) ● タイプ・パターンや switch のプリミティブの非対称性については、まだ改善すべき点がある。 ● もし、double を受け取るコンストラクタがある場合: public JsonNumber(double x) { … } ● コンストラクタに int を与えられる。 Json j = new JsonNumber(3) ● しかし、それを出コンストラクトして int 型を入れ子にできない。 case JsonNumber(int x): case JsonNumber(double x): ● さらに悪いことに、手動で double を int にキャストできるが、それは損失が大きい。 ● これは「赤いボール」のケースで見たのと同じような非対称性である。 P. 41

Slide 12

Slide 12 text

12 Primitive type patterns (作業中) ● Instanceof とキャストは深い関係にある。 ○ Instanceof は基本的に「この型にキャストしても安全かどうか 」を問うものである。 ○ 参照型の場合、これはサブタイプ化と一致する。 ○ プリミティブ型の場合、instanceof は現在のところ未定義である。 ● instanceof を「例外なく・精度を落とさずにキャストが成功するか 」という意味に一般化できる ○ 0 は instanceof byte だが、1000 はそうではない。 ● instanceof の定義の拡張にあわせて、プリミティブ型のパターンを定義できる。つまり case JsonNumber(int x): は普通のパターン合成に過ぎないのか、それともターゲットがJsonNumberで、その double の要素は int に損なわれることなく収まる値を含んでいるのか ● また、float/double/boolean定数のケース・ラベルもサポートしている。 P. 42

Slide 13

Slide 13 text

13

Slide 14

Slide 14 text

linkedin.com/company/red-hat youtube.com/user/RedHatVideos facebook.com/redhatinc twitter.com/RedHat 14