今日の参考文献 (1)
OpenJDK Project Valhalla のメインサイト
• https://openjdk.org/projects/valhalla/
Background Documents
• 1. The Road to Valhalla
• 2. The Language Model
• 3. The JVM Model
今日の参考文献 (4) LWorld
JVM Language Summit 2018 のセッション
LWorld: the next steps on the journey to Valhalla with David
Simms & Tobi Ajila
• https://www.youtube.com/watch?v=_26KZAegYRM&t=1s
Project Valhalla Early-Access Builds (試作版のJava)
• https://jdk.java.net/valhalla/
L-World
検証用の試作版JavaVM
• https://jdk.java.net/valhalla/
オブジェクトモデルの検証用なのでいろいろと不完全
2023/03/30時点では LW4 というバージョンになっている
JVM Language Summit 2018 のセッション
LWorld: the next steps on the journey to Valhalla with David Simms
& Tobi Ajila
• https://www.youtube.com/watch?v=_26KZAegYRM&t=1s
Value Objects と Identity Objects
nullの使用 不変性 同値判定
Identity Objects Record 可 不変 equals
Class 可 可変 equals
Interface 可 可変 equals
Array 可 可変 Arrays.deepEquals
Enum * 可 不変 ==
Value Objects Record 可 不変 ==
Class 可 不変 ==
Primitive 不可 不変 ==
Enum は理論的には Value Object 足りうるが、java.lang.Enum が要件を満たさないため、現
時点ではIdentity Object になれない
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-
model#value-records
Slide 14
Slide 14 text
Value Objects と Identity Objects
Value Objects も Identity Objects も一見同じように見えます
IdentityClass id = new IdentityClass();
double d = id.doubleValue();
ValueClass v = new ValueClass();
double d = v.doubleValue();
int i = 12;
double d = i.doubleValue();
Slide 15
Slide 15 text
Valhalla のスローガン
Codes like a class, works like an int.
クラスのように書き、intのように動く。
Slide 16
Slide 16 text
Value クラス
identity class Id1 {
int counter = 0;
void increment() { counter++; }
}
value class ValueClass {
int counter = 0;
void increment() { counter++; } // コンパイルエラー!
}
Value Objects は不変(Immutable)です。
暗黙にfinal
Slide 17
Slide 17 text
Value Objects の同値判定
Value Objects では == で同値判定することができます
ValueClass v1 = new ValueClass();
ValueClass v2 = new ValueClass();
System.out.println(v1 == v2); // true
IdentityClass id1 = new IdentityClass();
IdentityClass id2 = new IdentityClass();
System.out.println(id1 == id2); // false
Slide 18
Slide 18 text
プリミティブ型
boolean, char, byte, short, int, long, float, double の8種
• リテラルが使える
• 演算子が使える
• == で同値判定できる
• メソッドの呼び出しができる
• null を使えない
• ジェネリクスでも利用可能
new ArrayList();
new ArrayList();
new ArrayList();
Slide 19
Slide 19 text
Record
Record を用いるとデータを保持する不変クラスを
簡単に定義できます
Record は identity / value いずれでも宣言することができます
public identity record IdentityRecord (int id, String name) {}
public value record ValueRecord (int id, String name) {}
Slide 20
Slide 20 text
Valhalla はやさしい世界
俺たちは雰囲気でValhallaで戦える!
Slide 21
Slide 21 text
Valhalla の裏方は地獄
互換性キープで!
既存のは Value と
Identity に再整理な!
Slide 22
Slide 22 text
プリミティブ型のメソッド呼び出し
プリミティブ型変数に “.” や “::” を付けた場合にラッパークラ
スを探してメソッドを呼び出す仕組み
int i = 12;
int iSize = i.SIZE;
double iAsDouble = i.doubleValue();
Supplier iSupp = i::toString;
JEP 402 の Member accesses の項参照
左辺がリテラルの時、”.”をどう解釈するか問題とかがある
Slide 23
Slide 23 text
Value でも Identity でもない class
以下のいずれかのプロパティを持つ場合、暗黙的にIdentity
• abstract ではなく、classではないクラスがabstractであり、Objectクラスでもない
• クラスがabstractで、インスタンスフィールドを宣言している(8.3.1.1)か、または包含
インスタンスを持っている(8.1.3)
• クラスがabstractで、同期されたインスタンスメソッドを宣言している(8.4.3.6)
• クラスがabstractで、非自明なコンストラクタ(8.8)またはインスタンスイニシャライ
ザ(8.6)を宣言している。このルールの目的で、コンストラクタは、アクセスレベルが
クラスよりも厳格である(8.8.3)、フォーマルパラメータ(8.8.1)または型パラメータ
(8.8.4)を宣言する、throws句(8.8.5)を持つ、またはsuper();という形式の明示的な
コンストラクタ呼び出し以外の何かを含む場合に、"非自明"と見なされます(8.8.7)
言語仕様 8.1.1.5 identity and value Classes より
分からん!
Slide 24
Slide 24 text
How We Got the Generics We Have
互換性を維持しつつ機能追加?
それ20年前にジェネリクスでやったわ
https://openjdk.org/projects/valhalla/design-notes/in-defense-of-erasure
互換性は大事。徐々に移行できるように
Slide 25
Slide 25 text
ジェネリクスのプリミティブ 型変数
List は List にマッピングする。
境界チェックの前にこの変換をやるよ。
ここで T! T? T* というnullを許容するかどうかの型変
数を導入してうまいこと辻褄合わせるよ。
T! Nullness
T? Nullable
T* T! or T?
'!' <: '*' <: '?'
JEP 208
JEP 402
ML : Nullness markers