Slide 1

Slide 1 text

Value Types et Pattern Matching Remettre les données au centre des applications José Paumard Java Developer Advocate Java Platform Group Rémi Forax Maître de conferences Université Gustave Eiffel

Slide 2

Slide 2 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 2 https://dev.java/

Slide 3

Slide 3 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 3 Tune in! Inside Java Newscast JEP Café Dev.java Inside.java Inside Java Podcast Sip of Java Cracking the Java coding interview

Slide 4

Slide 4 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 4 https://dev.java/community/

Slide 5

Slide 5 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 5 https://openjdk.org/ OpenJDK is the place where it all happens

Slide 6

Slide 6 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 6 https://jdk.java.net/ OpenJDK is the place where it all happens

Slide 7

Slide 7 text

https://twitter.com/JosePaumard https://github.com/JosePaumard https://www.youtube.com/c/JosePaumard01 https://www.youtube.com/user/java https://www.youtube.com/hashtag/jepcafe https://fr.slideshare.net/jpaumard https://www.pluralsight.com/authors/jose-paumard https://dev.java

Slide 8

Slide 8 text

https://twitter.com/He bah non! https://github.com/forax https://speakerdeck.com/forax OpenJDK, ASM, Tatoo, Pro, etc… One of the Father of invokedynamic (Java 7) Lambda (Java 8), Module (Java 9) Constant dynamic (Java 11) Record, text blocks, sealed types (Java 14 / 15) Valhalla (Java 19+)

Slide 9

Slide 9 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 9 Data Oriented Programming Amber Java on modern CPU Valhalla + Lilliput Java in the cloud Leyden + Crac + Galahad Foreign functions API (C) + Vector API Panama Modernizing Java

Slide 10

Slide 10 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 10 Amber

Slide 11

Slide 11 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 11 Java is OOP!

Slide 12

Slide 12 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 12 Encapsulation OOP according to Java class City { private String name; public String toString() { ... } }

Slide 13

Slide 13 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 13 Interface and sub-typing OOP according to Java class City implements Named { ... } Named named = new City(...);

Slide 14

Slide 14 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 14 Late binding (virtual polymorphism) OOP according to Java class City { public String toString() { ... } } Named named = new City(...); var name = named.toString(); // calls City.toString()

Slide 15

Slide 15 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 15 Anatomy of a Web Application Browser request request response Your code! JSON API DB API Authentication API SUCCESS STORY! REST API

Slide 16

Slide 16 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 16 OOP in Java APIs (interfaces) are more important than code

Slide 17

Slide 17 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 17 DOP in Java Data first! Data are more important that code When the data changes, the compiler helps

Slide 18

Slide 18 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 18 Model the problem using a class and an interface + late binding Object Oriented Programming final class City implements Named { private final String name; private final int population; public String name() { return name; } } final class Department implements Named { private final String name; public String name() { return name; } } interface Named { public String name(); }

Slide 19

Slide 19 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 19 Encapsulation  defensive copy in constructors OOP + Defensive Copy final class Department implements Named { private final String name; private final List cities; public Department(String name, List cities) { this.name = Objects.requireNonNull(name); this.cities = List.copyOf(cities); } }

Slide 20

Slide 20 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 20 Separate Data and Code Data Oriented Programming interface Named { } final class City implements Named { } final class Department implements Named { } static String name(Named named) { if (named instanceof City) { var city = (City) named; if (city.population() < 0) { throw new ISE("danger danger"); } return city.name(); } if (named instanceof Department) { var department = (Department) named; return department.name(); } throw new AssertionError(); }

Slide 21

Slide 21 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 21

Slide 22

Slide 22 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 22 Data is more important than code - Not always true Compiler helps (like with OOP) - Records are data definition - Sealed types make switch exhaustive - Record patterns detect structural modification Data Oriented Programming

Slide 23

Slide 23 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 23 Polymorphism - Add new subtypes - No new operations Wadler’s Expression of the Problem Pattern Matching - Add new operations - No new subtypes You cannot get both  If you are not the owner of the code:

Slide 24

Slide 24 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 24 To avoid the creation of bindings Or relax constraints Also works on local variables, for, try-with-resources, … Does not work on method declaration (APIs must have a name) More Patterns: Unnamed Pattern case City(String _, int population) -> ...; case Department(String name, _) -> ...;

Slide 25

Slide 25 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 25 Deconstructor enables record pattern on class More Patterns: Record Pattern on Classes class Point { private int x, y; matcher(int x, int y) Point { // provisional syntax match this.x, this.y; } }

Slide 26

Slide 26 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 26 Allows matcher methods to be named Named Pattern final class Optional { final private T value; final private boolean present; matcher(T t) of { // provisional syntax if (present) match this.value; no-match; } matcher() empty { // provisional syntax if (present) match; no-match; } } Optional opt = ...; switch(opt) { case Optional.of(String s) -> ...; case Optional.empty() -> }

Slide 27

Slide 27 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 27 Using record pattern in assignments Imperative Destructuring Point p = ...; let Point(int x, int y) = p; for (let Map.Entry(var key, var value): entrySet) { ... }

Slide 28

Slide 28 text

Coffee (or whatever) Break!

Slide 29

Slide 29 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 29 Valhalla

Slide 30

Slide 30 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 30 Valhalla

Slide 31

Slide 31 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 31 Valhalla

Slide 32

Slide 32 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 32 Why does nobody follow this principle? Valhalla

Slide 33

Slide 33 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 33 Summing populations Primitive Types or Objects? int[] populations = {...}; int totalPopulation = 0; for (int population: populations) { totalPopulation += population; } int totalPopulation = Arrays.stream(populations).sum(); record Population(int population) {} Population[] populations = {...}; Population total = 0; for (Population pop: populations) { total = total.add(pop); } Population total = Arrays.stream(populations) .reduce( Population.zero(), Population::add);

Slide 34

Slide 34 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 34 Creating histograms Primitive Types or Objects? // this is the histogram of population by city Map populationByCity = ...; record City(String name, Population population) {} record Population(int population) {} Map populationByCity = ...;

Slide 35

Slide 35 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 35 1st goal: make it so that you do not have to choose between readable code and performances Make abstraction (almost) free Codes like a class, Works like an int Valhalla

Slide 36

Slide 36 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 36 The performances of both patterns should be the same Valhalla: goals int[] populations = {...}; int totalPopulation = 0; for (int population: populations) { totalPopulation += population; } record Population(int population) {} Population[] populations = {...}; Population total = 0; for (Population pop: populations) { total = total.add(pop); }

Slide 37

Slide 37 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 37 Abstraction for free (on stack) - No allocation of intermediate objects Improved information density (on heap) - No header - Use immediate value (no pointer) Valhalla: goals

Slide 38

Slide 38 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 38 Temporary objects should be free - Optional - True builders - Logger.warning() .onConsole("Hello Devoxx!"); Wrapped values should be free - Integer, Complex, Month, LocalDate, etc… Abstraction for Free (on Stack)

Slide 39

Slide 39 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 39 Integer[] array = new Integer[4]; Improve Information Density (on Heap) header header = 32 + 64 bits (heap < 32GB) 64 + 64 bits header header header header

Slide 40

Slide 40 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 40 High level goal: realign Java with the current hardware Valhalla is an OpenJDK project started in 2014 by Brian Goetz and John Rose - August 2014: first meeting - 2017 – 2022: MVT, LW1, LW2, LW3, LW4 (prototypes) - 202?: LW5, Value classes as a Preview feature - 20??: Universal Specialized Generics Valhalla in detail

Slide 41

Slide 41 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 41 Value types in LW5 LW5 is still under construction VM almost ready Compiler not ready But we have a bytecode rewriter!

Slide 42

Slide 42 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 42 Summing the populations of Cities Primitives vs. Objects int total = 0; for (City city: cities) { total += city.population(); } record City(String name, int population) {} City[] cities = ...;

Slide 43

Slide 43 text

Copyright © 2021, Oracle and/or its affiliates | 43 Extra pointers / space in memory Layout in Memory cities String int Primitive version

Slide 44

Slide 44 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 44 Summing the populations of Cities Primitives vs. Objects int total = 0; for (City city: cities) { total += city.population(); } record Population(int population) {} record City(String name, Population population) {} Population total = new Population(0); for (Population pop: populations) { total = total.add(pop); } City[] cities = ...; record City(String name, int population) {} City[] cities = ...;

Slide 45

Slide 45 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 45 Extra pointers / space in memory Layout in Memory cities Population int String int cities String population Primitive version Object version

Slide 46

Slide 46 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 46 Extra allocations / indirections Instructions on Stack int total = 0; for (City city: cities) { total += city.population(); } record Population(int population) {} record City(String name, Population population) {} Population total = new Population(0); for (Population pop: populations) { total = new Population( total.population + pop.population); } City[] cities = ...; record City(String name, int population) {} City[] cities = ...;

Slide 47

Slide 47 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 47 Two different effects: - Operations on stack (extra instructions) - Memory layout (extra indirections) Can be solved separately: - Escape analysis - Soving memory layout involves tradeoffs Primitive vs. Objects

Slide 48

Slide 48 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 48 A class that gives up its identity Instances have no address in memory But still: - Inherits from java.lang.Object - Implements interfaces - Defines members (methods, fields, nested classes, …) - Values are references / instances of the class (or null) What is a Value Class?

Slide 49

Slide 49 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 49 Declaration Scalarization: on the stack, the JVM replaces an instance by its field values (if not null) What is a Value Class? public value class Population { final int population; }

Slide 50

Slide 50 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 50 On the stack declaring Is equivalent to: What is a Value Class? Population population = new Population(23); int population = 23;

Slide 51

Slide 51 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 51 Problem with method calls - Method calls should pass an address…  the fields have to be unmodifiable - All fields are declared final - But that’s not enough! Value Classes are Non-Modifiable

Slide 52

Slide 52 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 52 Final fields can be modified during the execution of a constructor  the constructor is transformed into a chain of static methods, each call creates a new value class instance - All fields are declared final - But that’s not enough! Constructor Issue

Slide 53

Slide 53 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 53 Value Class Constructor value class Population { final int population; Population(int pop) { this.population = pop; } } value class Population { final int population; static Population(int value) { var tmp1 = aconst_init Population var tmp2 = withfield Population.value(tmp1, value) return tmp2 } } Generated by javac

Slide 54

Slide 54 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 54 Operations that requires an address or values from the header need a different semantics == recursively calls == on the fields System.identityHashCode() calls Objects.hash() on all fields Value Class Semantics

Slide 55

Slide 55 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 55 Operations that requires an address or values from the header need a different semantics synchronized throws IllegalMonitorStateException new WeakRef(value) throws IndentityException Value Class Semantics

Slide 56

Slide 56 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 56 Compounds with existing issues: Bad CPU branch prediction VM deoptimization GC read barrier (Shenandoah and ZGC) Don’t use == in Object.equals()! value class Population { public boolean equals(Object other) { if (other == this) return true: // ahhhhh ... } }

Slide 57

Slide 57 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 57 Use Pattern Matching instead value class Population { final int pop; public boolean equals(Object o) { return o instanceof Population other && other.pop == this.pop; } … }

Slide 58

Slide 58 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 58 Demo Civilizer

Slide 59

Slide 59 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 59 V1: City is a regular record, Population is an int V2: City and Population are regular records Bench: Population of Cities with Regular Records record City(String name, int population) {} record City(String name, Population population) {} record Population(int amount) {}

Slide 60

Slide 60 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 60 Bench: Population of Cities with Regular Records City[] cities = ...; int sum = 0; for (City city: cities) { sum += city.population(); } Benchmark V1 Score Error Units sum populations 24,985 ± 0,097 us/op Population total = Population.zero(); for (City city: cities) { total = total.add(city.population()); } Benchmark V2 Score Error Units sum populations 68,069 ± 0,686 us/op City[] cities = ...; int sum = 0; for (City city: cities) { sum += city.population().amount(); } Benchmark V2 Score Error Units sum populations 33,335 ± 0,140 us/op

Slide 61

Slide 61 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 61 V3: City is a regular record, Population is a value record Bench: Population of Cities with Value Records record City(String name, Population population) {} record Population(int amount) {}

Slide 62

Slide 62 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 62 Bench: Population of Cities with Value Records City[] cities = ...; int sum = 0; for (City city: cities) { sum += city.population(); } (same as previous) Benchmark Score Error Units sum populations 24,985 ± 0,097 us/op Population total = Population.zero(); for (City city: cities) { total = total.add(city.population()); } Benchmark V3 Score Error Units sum populations 35,012 ± 0,128 us/op City[] cities = ...; int sum = 0; for (City city: cities) { sum += city.population().amount(); } Benchmark V3 Score Error Units sum populations 34,954 ± 0,309 us/op

Slide 63

Slide 63 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 63 Fields cannot be flattened easily: - we cannot represent null (what should be the default value?) - concurrency issue if the CPU does several stores / loads for on field The Field of a Value Class (or Array)? class City { final Population population; }

Slide 64

Slide 64 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 64 Allows to declare that a type does not allow null proposed syntax: Population! the VM can throw a NPE if null is assigned Only need for fields and array elements Add Emotion on Type

Slide 65

Slide 65 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 65 Users should not be able to define the default values Java is not C++ !  All fields are zeroed (false, 0, 0.0, etc…)  but this breaks encapsulation Non Null Default Value Classes

Slide 66

Slide 66 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 66 Add a default empty constructor  enables a non null value class Value Class with a Default Instance value class Population { // proposed syntax final int value; default Population(); // default empty constructor Population(int value) { this.value = value; } }

Slide 67

Slide 67 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 67 Use the ! (emotion, bang) character Only valid if Population is a value class with a default instance Defining a Non-Null Element value record City(String name, Population! population) {} var populationArray = new Population![10]; List populationList = new ArrayList<>();

Slide 68

Slide 68 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 68 V4: Population is a value record with a default instance, City declares it as a non-null field Bench: Value Class with Default Instance record Population(int amount) { default population(); } record City(String name, Population! population) {}

Slide 69

Slide 69 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 69 Bench: with Value Class, Defaut Instance, Non Null City[] cities = ...; int sum = 0; for (City city: cities) { sum += city.population(); } (same as previous) Benchmark Score Error Units sum populations 24,985 ± 0,097 us/op Population! total = Population.zero(); for (City city: cities) { total = total.add(city.population()); } Benchmark V4 Score Error Units sum populations 25,343 ± 0,028 us/op City[] cities = ...; int sum = 0; for (City city: cities) { sum += city.population().amount(); } Benchmark V4 Score Error Units sum populations 25,230 ± 0,045 us/op

Slide 70

Slide 70 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 70 Array of Pointers Layout in Memory Population int cities String population City[] Object version

Slide 71

Slide 71 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 71 Array of Pointers of Population Struct Layout in Memory cities String Population City[] / Population! version

Slide 72

Slide 72 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 72 Array of Struct Layout in Memory cities String Population City![] / Population! version String Population String Population String Population

Slide 73

Slide 73 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 73 Bench: with Value Class, Defaut Instance, Non Null City![] cities = ...; int sum = 0; for (City city: cities) { sum += city.population(); } (same as previous) Benchmark Score Error Units sum populations 24,985 ± 0,097 us/op Population! total = Population.zero(); for (City! city: cities) { total = total.add(city.population()); } Benchmark Score Error Units sum populations 11,087 ± 0,005 us/op City![] cities = ...; int sum = 0; for (City! city: cities) { sum += city.population().amount(); } Benchmark Score Error Units sum populations 11,098 ± 0,011 us/op

Slide 74

Slide 74 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 74 Concurrency

Slide 75

Slide 75 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 75 Do we Have a Concurrency Issue? value record City(int population, int surface) {}

Slide 76

Slide 76 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 76 Do we Have a Concurrency Issue? class Holder { private City! city = new City(1, 1); public static void main(String[] args) { Holder holder = new Holder(); new Thread( () -> { for(;;) holder.city = new City(1, 1); } ).start(); new Thread( () -> { for(;;) holder.city = new City(2, 2); } ).start(); ... } }

Slide 77

Slide 77 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 77 Do we Have a Concurrency Issue? for(;;) { City city = holder.city; if (city.population != city.surface) { throw new AssertionError("" + city); } }

Slide 78

Slide 78 text

@Holder 5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 78 Do we Have a Concurrency Issue? population surface 1 2 1, 1 2, 2

Slide 79

Slide 79 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 79 Easy to solve, do not use City! Cheap Solution! class Holder { private City city = new City(1, 1); public static void main(String[] args) { ... } }

Slide 80

Slide 80 text

@City @Holder 5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 80 Cheap Solution! city 1, 1 2, 2 population surface 1 2

Slide 81

Slide 81 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 81 Make value classes always atomic by default We need a non-atomic flag (not yet implemented in the JVM) Non-atomic non-atomic value record Population(int amount) { // proposed syntax default Population(); // default empty constructor }

Slide 82

Slide 82 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 82 Valhalla + Amber? What if there is an interface? What if there is a switch on types?

Slide 83

Slide 83 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 83 Hierarchy on Named Elements sealed interface Named permits City, Department, Region {} record Population(int amount) {} record City(String name, Population population) implements Named {} record Department(List cities, String name) implements Named {} record Region(List department, String name) implements Named {}

Slide 84

Slide 84 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 84 Minimum Name Length static String name(Named named) { return switch(named) { case City city -> city.name(); case Department department -> department.name(); case Region region -> region.name(); }; } static Named min(Named n1, Named n2) { if (name(n1).compareTo(name(n2) < 0) { return n1; } return n2; }

Slide 85

Slide 85 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 85 Switch not yet fully optimized Switch + value: bimodal perf? OOP vs. Switch / Identity Value OOP + Records Switch + Records OOP + Value Records Switch + Value Records Score Error Units 320,742 ± 1,122 ns/op 434,220 ± 1,543 ns/op Score Error Units 248,244 ± 1,489 ns/op 424,537 ± 35,296 ns/op

Slide 86

Slide 86 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 86 Aaaaahh, a lot of boxing!  we need specialized generics Bench: default instance value class Score Error Units 320,742 ± 1,122 ns/op 434,220 ± 1,543 ns/op Score Error Units 248,244 ± 1,489 ns/op 424,537 ± 35,296 ns/op OOP + Records Switch + Records OOP + Value Records Switch + Value Records Score Error Units 1666,613 ± 638,825 ns/op 2167,923 ± 455,078 ns/op OOP + Default Value Records Switch + Default Value Records

Slide 87

Slide 87 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 87 Future

Slide 88

Slide 88 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 88 Generalize and allow ! and ? on identity classes too Is equivalent to: Emotion Type on Identity Classes? void foo(String! s) { ... } void foo(String s) { Objects.requireNonNull(s); ... } And also the inverse so the default is ! ? means nullable See JSpecify.org

Slide 89

Slide 89 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 89 All the value based classes of the JDK are retrofitted to be value classes - Optional, LocalDateTime, are value classes - Booean, Integer, Double, etc… are non-atomic value classes with a default instance Existing Classes Retrofited

Slide 90

Slide 90 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 90 Non null default instance Value class No pointer, great, until boxing  Generics needs to be specialized (but backward compatible) ArrayList is flattened N min(N n1, N n2) is JITed several times Specialized Generics

Slide 91

Slide 91 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 91 Bridge the gap: - Allow method calls (equals() toString() hashCode()) on primitive literals - true.toString() - 2.equals(3) // parsing error 2. is a double - Allow ArrayList - int is a subtype of Integer for overriding - Automatic conversions between int[] and Integer![] Primitive and Value Classes

Slide 92

Slide 92 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 92 Executive Summary

Slide 93

Slide 93 text

5/5/2023 Copyright © 2021, Oracle and/or its affiliates | 93 What You are Giving Up, What You Get Identity Class Value Class Non-Null Value Class with a Default Instance Non-Null Non-Atomic Value Class with a Default Instance Address in memory Null + encapsulation of default value Atomicity of load / store Scalarization on the stack Flattening of small classes Flattening of medium classes

Slide 94

Slide 94 text

Time for questions? Valhalla rocks!

Slide 95

Slide 95 text

Valhalla rocks!