Slide 1

Slide 1 text

What's new in Java 19: The end of Kotlin? @JakeWharton

Slide 2

Slide 2 text

January 23, 1996 Java 1

Slide 3

Slide 3 text

September 30, 2004 Java 5

Slide 4

Slide 4 text

July 28, 2011 Java 7

Slide 5

Slide 5 text

March 18, 2014 Java 8

Slide 6

Slide 6 text

September 21, 2017 Java 9

Slide 7

Slide 7 text

September 21, 2017 Java 9 March 20, 2018 Java 10

Slide 8

Slide 8 text

March 20, 2018 Java 10 September 25, 2018 Java 11

Slide 9

Slide 9 text

September 25, 2018 Java 11 March 19, 2019 Java 12

Slide 10

Slide 10 text

March 19, 2019 Java 12 September 17, 2019 Java 13

Slide 11

Slide 11 text

March 2020 Java 14 September 2020 Java 15

Slide 12

Slide 12 text

March 2021 Java 16 September 2021 Java 17

Slide 13

Slide 13 text

March 2022 Java 18 September 2022 Java 19

Slide 14

Slide 14 text

8 September 2022 Java 19

Slide 15

Slide 15 text

8 September 2022 Java 19 YOU ARE HERE

Slide 16

Slide 16 text

Variable Type Inference

Slide 17

Slide 17 text

var count = 1

Slide 18

Slide 18 text

var count = 1 var count = 1

Slide 19

Slide 19 text

var count = 1 val users = mutableListOf() var count = 1

Slide 20

Slide 20 text

var count = 1 val users = mutableListOf() var count = 1 final var users = new ArrayList()

Slide 21

Slide 21 text

var count = 1 val users = mutableListOf() var default: String? = null var count = 1 final var users = new ArrayList()

Slide 22

Slide 22 text

var count = 1 val users = mutableListOf() var default: String? = null var count = 1 final var users = new ArrayList() String default = null

Slide 23

Slide 23 text

var count = 1 val users = mutableListOf() var default: String? = null val tasks: Deque = ArrayDeque() var count = 1 final var users = new ArrayList() String default = null

Slide 24

Slide 24 text

var count = 1 val users = mutableListOf() var default: String? = null val tasks: Deque = ArrayDeque() var count = 1 final var users = new ArrayList() String default = null Deque tasks = new ArrayDeque<>()

Slide 25

Slide 25 text

val run1: () -> Unit = { /* .. */ }

Slide 26

Slide 26 text

val run1: () -> Unit = { /* .. */ } val run2 = { /* .. */ }

Slide 27

Slide 27 text

val run1: () -> Unit = { /* .. */ } val run2 = { /* .. */ } Runnable run1 = () -> { /* .. */ };

Slide 28

Slide 28 text

val run1: () -> Unit = { /* .. */ } val run2 = { /* .. */ } Runnable run1 = () -> { /* .. */ }; var run2 = () -> { /* .. */ };

Slide 29

Slide 29 text

val run1: () -> Unit = { /* .. */ } val run2 = { /* .. */ } Runnable run1 = () -> { /* .. */ }; var run2 = new Runnable() { @Override public void run() { /* .. */ } };

Slide 30

Slide 30 text

var count = 1 val users = mutableListOf() var default: String? = null val tasks: Deque = ArrayDeque() val run1: () -> Unit = { /* .. */ } val run2 = { /* .. */ } var count = 1 final var users = new ArrayList() String default = null Deque tasks = new ArrayDeque<>() Runnable run1 = () -> { /* .. */ }; var run2 = new Runnable() { @Override public void run() { /* .. */ } };

Slide 31

Slide 31 text

Local Functions

Slide 32

Slide 32 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 33

Slide 33 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 34

Slide 34 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 35

Slide 35 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 36

Slide 36 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 37

Slide 37 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() } public static boolean any(Predicate predicate) { var seen = new HashSet(); boolean hasMatch(Node node) { if (!seen.add(node)) return false; // already seen if (predicate.test(node)) return true; // match! return node.getNodes().stream().anyMatch(n -> hasMatch(n)); } return hasMatch(getRoot()); }

Slide 38

Slide 38 text

public static boolean any(Predicate predicate) { var seen = new HashSet(); boolean hasMatch(Node node) { if (!seen.add(node)) return false; // already seen if (predicate.test(node)) return true; // match! return node.getNodes().stream().anyMatch(n -> hasMatch(n)); } return hasMatch(getRoot()); }

Slide 39

Slide 39 text

public static boolean any( Graph, java.util.function.Predicate); Code: 0: new #7 // class java/util/HashSet 3: dup 4: invokespecial #9 // Method java/util/HashSet."":()V 7: astore_2 8: aload_2 9: aload_1 10: aload_0 11: invokevirtual #10 // Method getRoot:()Lcom/example/Node; 14: invokestatic #16 // Method local$any$0(...)Z 17: ireturn private static boolean local$any$0( java.util.HashSet, java.util.function.Predicate, Node); Code: ...

Slide 40

Slide 40 text

public static boolean any( Graph, java.util.function.Predicate); Code: 0: new #7 // class java/util/HashSet 3: dup 4: invokespecial #9 // Method java/util/HashSet."":()V 7: astore_2 8: aload_2 9: aload_1 10: aload_0 11: invokevirtual #10 // Method getRoot:()Lcom/example/Node; 14: invokestatic #16 // Method local$any$0(...)Z 17: ireturn private static boolean local$any$0( java.util.HashSet, java.util.function.Predicate, Node); Code: ...

Slide 41

Slide 41 text

public static boolean any( Graph, java.util.function.Predicate); Code: 0: new #7 // class java/util/HashSet 3: dup 4: invokespecial #9 // Method java/util/HashSet."":()V 7: astore_2 8: aload_2 9: aload_1 10: aload_0 11: invokevirtual #10 // Method getRoot:()Lcom/example/Node; 14: invokestatic #16 // Method local$any$0(...)Z 17: ireturn private static boolean local$any$0( java.util.HashSet, java.util.function.Predicate, Node); Code: ...

Slide 42

Slide 42 text

public static boolean any(Predicate predicate) { var seen = new HashSet(); boolean hasMatch(Node node) { if (!seen.add(node)) return false; // already seen if (predicate.test(node)) return true; // match! return node.getNodes().stream().anyMatch(n -> hasMatch(n)); } return hasMatch(getRoot()); }

Slide 43

Slide 43 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 44

Slide 44 text

public static boolean any( Graph, kotlin.jvm.functions.Function1); Code: 0: new #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."":()V 7: astore_2 8: new #26 // class GraphKt$any$1 11: dup 12: aload_2 13: aload_1 14: invokespecial #29 // Method GraphKt$any$1."": (Ljava/util/HashSet; Lkotlin/jvm/functions/Function1;)V 17: astore_3 18: aload_3 19: aload_0 20: invokeinterface #35, 1 // InterfaceMethod Graph.getRoot:()LNode; 25: invokevirtual #39 // Method GraphKt$any$1.invoke:(LNode;)Z 28: ireturn

Slide 45

Slide 45 text

public static boolean any( Graph, kotlin.jvm.functions.Function1); Code: 0: new #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."":()V 7: astore_2 8: new #26 // class GraphKt$any$1 11: dup 12: aload_2 13: aload_1 14: invokespecial #29 // Method GraphKt$any$1."": (Ljava/util/HashSet; Lkotlin/jvm/functions/Function1;)V 17: astore_3 18: aload_3 19: aload_0 20: invokeinterface #35, 1 // InterfaceMethod Graph.getRoot:()LNode; 25: invokevirtual #39 // Method GraphKt$any$1.invoke:(LNode;)Z 28: ireturn

Slide 46

Slide 46 text

public static boolean any( Graph, kotlin.jvm.functions.Function1); Code: 0: new #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."":()V 7: astore_2 8: new #26 // class GraphKt$any$1 11: dup 12: aload_2 13: aload_1 14: invokespecial #29 // Method GraphKt$any$1."": (Ljava/util/HashSet; Lkotlin/jvm/functions/Function1;)V 17: astore_3 18: aload_3 19: aload_0 20: invokeinterface #35, 1 // InterfaceMethod Graph.getRoot:()LNode; 25: invokevirtual #39 // Method GraphKt$any$1.invoke:(LNode;)Z 28: ireturn

Slide 47

Slide 47 text

public static boolean any( Graph, kotlin.jvm.functions.Function1); Code: 0: new #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."":()V 7: astore_2 8: new #26 // class GraphKt$any$1 11: dup 12: aload_2 13: aload_1 14: invokespecial #29 // Method GraphKt$any$1."": (Ljava/util/HashSet; Lkotlin/jvm/functions/Function1;)V 17: astore_3 18: aload_3 19: aload_0 20: invokeinterface #35, 1 // InterfaceMethod Graph.getRoot:()LNode; 25: invokevirtual #39 // Method GraphKt$any$1.invoke:(LNode;)Z 28: ireturn

Slide 48

Slide 48 text

final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1 { final java.util.HashSet $seen; final kotlin.jvm.functions.Function1 $predicate; GraphKt$any$1(java.util.HashSet, kotlin.jvm.functions.Function1); Code: ... public final boolean invoke(Node); Code: ... }

Slide 49

Slide 49 text

final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1 { final java.util.HashSet $seen; final kotlin.jvm.functions.Function1 $predicate; GraphKt$any$1(java.util.HashSet, kotlin.jvm.functions.Function1); Code: ... public final boolean invoke(Node); Code: ... }

Slide 50

Slide 50 text

final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1 { final java.util.HashSet $seen; final kotlin.jvm.functions.Function1 $predicate; GraphKt$any$1(java.util.HashSet, kotlin.jvm.functions.Function1); Code: ... public final boolean invoke(Node); Code: ... }

Slide 51

Slide 51 text

final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1 { final java.util.HashSet $seen; final kotlin.jvm.functions.Function1 $predicate; GraphKt$any$1(java.util.HashSet, kotlin.jvm.functions.Function1); Code: ... public final boolean invoke(Node); Code: ... }

Slide 52

Slide 52 text

final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1 { final java.util.HashSet $seen; final kotlin.jvm.functions.Function1 $predicate; GraphKt$any$1(java.util.HashSet, kotlin.jvm.functions.Function1); Code: ... public final boolean invoke(Node); Code: ... }

Slide 53

Slide 53 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() }

Slide 54

Slide 54 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() } "Optimize generation of local functions" youtrack.jetbrains.com/issue/KT-6336

Slide 55

Slide 55 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() } "Consider more aggresively removing classes from Kotlin local functions" issuetracker.google.com/issues/145231155

Slide 56

Slide 56 text

fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen = HashSet() fun Node.hasMatch(): Boolean { if (!seen.add(this)) return false // already seen if (predicate(this)) return true // match! return nodes.any { it.hasMatch() } } return root.hasMatch() } public static boolean any(Predicate predicate) { var seen = new HashSet(); boolean hasMatch(Node node) { if (!seen.add(node)) return false; // already seen if (predicate.test(node)) return true; // match! return node.getNodes().stream().anyMatch(n -> hasMatch(n)); } return hasMatch(getRoot()); }

Slide 57

Slide 57 text

Multiline Strings

Slide 58

Slide 58 text

fun main() { println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """) }

Slide 59

Slide 59 text

fun main() { println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """) } ····SELECT * ····FROM users ····WHERE name LIKE 'Jake %' ··

Slide 60

Slide 60 text

fun main() { println(""" |SELECT * |FROM users |WHERE name LIKE 'Jake %' |""".trimMargin()) } SELECT * FROM users WHERE name LIKE 'Jake %'

Slide 61

Slide 61 text

fun main() { println(""" !!!SELECT * !!!FROM users !!!WHERE name LIKE 'Jake %' !!!""".trimMargin(marginPrefix = "!!!")) } SELECT * FROM users WHERE name LIKE 'Jake %'

Slide 62

Slide 62 text

fun main() { println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """.trimIndent()) } SELECT * FROM users WHERE name LIKE 'Jake %' Margin m a r g i n P r e f i x = " ! ! ! "

Slide 63

Slide 63 text

fun main() { println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """.trimIndent()) } public static void main(String[] args) { System.out.println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """); }

Slide 64

Slide 64 text

public static void main(String[] args) { System.out.println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """); }

Slide 65

Slide 65 text

public static void main(String[] args) { System.out.println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """); } SELECT * FROM users WHERE name LIKE 'Jake %'

Slide 66

Slide 66 text

public static void main(String[] args) { System.out.println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """); } SELECT * FROM users WHERE name LIKE 'Jake %'

Slide 67

Slide 67 text

public static void main(String[] args) { System.out.println(""" SELECT * \ FROM users \ WHERE name LIKE 'Jake %' """); } SELECT * FROM users WHERE name LIKE 'Jake %'

Slide 68

Slide 68 text

assertThat(table.toString()).isEqualTo(""" |┌─┬─┐ ╷ |│ │ │ │ |├─┤ ╵ │ |│ │ │ |└─┼───┘ | │ |╶─┴─╴ |""".trimMargin())

Slide 69

Slide 69 text

assertThat(table.toString()).isEqualTo(""" ··|┌─┬─┐·╷ ··|│·│·│·│ ··|├─┤·╵·│ ··|│·│···│ ··|└─┼───┘ ··|··│···· ··|╶─┴─╴·· ··|""".trimMargin())

Slide 70

Slide 70 text

assertThat(table.toString()).isEqualTo(""" ··|┌─┬─┐·╷ ··|│·│·│·│ ··|├─┤·╵·│ ··|│·│···│ ··|└─┼───┘ ··|··│···· ··|╶─┴─╴·· ··|""".trimMargin()) assertThat(table.toString()).isEqualTo(""" ····┌─┬─┐·╷ ····│·│·│·│ ····├─┤·╵·│ ····│·│···│ ····└─┼───┘ ······│···· ····╶─┴─╴·· ····""");

Slide 71

Slide 71 text

assertThat(table.toString()).isEqualTo(""" ··|┌─┬─┐·╷ ··|│·│·│·│ ··|├─┤·╵·│ ··|│·│···│ ··|└─┼───┘ ··|··│···· ··|╶─┴─╴·· ··|""".trimMargin()) assertThat(table.toString()).isEqualTo(""" ····┌─┬─┐·╷ ····│·│·│·│ ····├─┤·╵·│ ····│·│···│ ····└─┼───┘ ······│···· ····╶─┴─╴·· ····""");

Slide 72

Slide 72 text

assertThat(table.toString()).isEqualTo(""" ··|┌─┬─┐·╷ ··|│·│·│·│ ··|├─┤·╵·│ ··|│·│···│ ··|└─┼───┘ ··|··│···· ··|╶─┴─╴·· ··|""".trimMargin()) assertThat(table.toString()).isEqualTo(""" ····┌─┬─┐·╷ ····│·│·│·│ ····├─┤·╵·│ ····│·│···│ ····└─┼───┘ ······│···\s ····╶─┴─╴·\s ····""");

Slide 73

Slide 73 text

println(""" Hey $name! Hola $name! Hello $name! """.trimIndent())

Slide 74

Slide 74 text

public static final void sayHi(java.lang.String); Code: 0: new #17 // class java/lang/StringBuilder 3: dup 4: invokespecial #21 // Method java/lang/StringBuilder."":()V 7: ldc #23 // String \n Hey 9: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 12: aload_0 13: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 16: ldc #29 // String !\n Hola 18: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 21: aload_0 22: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 25: ldc #31 // String !\n Hello 27: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 30: aload_0 31: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 34: ldc #33 // String !\n 36: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 39: invokevirtual #37 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 42: invokestatic #43 // Method kotlin/text/StringsKt.trimIndent:(Ljava/lang/String;)…; 45: astore_1 46: getstatic #49 // Field java/lang/System.out:Ljava/io/PrintStream; 49: aload_1 50: invokevirtual #55 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 53: return

Slide 75

Slide 75 text

public static final void sayHi(java.lang.String); Code: 0: new #17 // class java/lang/StringBuilder 3: dup 4: invokespecial #21 // Method java/lang/StringBuilder."":()V 7: ldc #23 // String \n Hey 9: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 12: aload_0 13: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 16: ldc #29 // String !\n Hola 18: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 21: aload_0 22: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 25: ldc #31 // String !\n Hello 27: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 30: aload_0 31: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 34: ldc #33 // String !\n 36: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 39: invokevirtual #37 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 42: invokestatic #43 // Method kotlin/text/StringsKt.trimIndent:(Ljava/lang/String;)…; 45: astore_1 46: getstatic #49 // Field java/lang/System.out:Ljava/io/PrintStream; 49: aload_1 50: invokevirtual #55 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 53: return

Slide 76

Slide 76 text

public static final void sayHi(java.lang.String); Code: 0: new #17 // class java/lang/StringBuilder 3: dup 4: invokespecial #21 // Method java/lang/StringBuilder."":()V 7: ldc #23 // String \n Hey 9: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 12: aload_0 13: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 16: ldc #29 // String !\n Hola 18: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 21: aload_0 22: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 25: ldc #31 // String !\n Hello 27: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 30: aload_0 31: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 34: ldc #33 // String !\n 36: invokevirtual #27 // Method java/lang/StringBuilder.append:(…)…; 39: invokevirtual #37 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 42: invokestatic #43 // Method kotlin/text/StringsKt.trimIndent:(Ljava/lang/String;)…; 45: astore_1 46: getstatic #49 // Field java/lang/System.out:Ljava/io/PrintStream; 49: aload_1 50: invokevirtual #55 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 53: return

Slide 77

Slide 77 text

println(""" Hey $name! Hola $name! Hello $name! """.trimIndent())

Slide 78

Slide 78 text

println(""" Hey $name! Hola $name! Hello $name! """.trimIndent()) System.out.println("" + "Hey " + name + "!\n" + " Hola " + name + "!\n" + " Hello " + name + "!");

Slide 79

Slide 79 text

System.out.println("" + "Hey " + name + "!\n" + " Hola " + name + "!\n" + " Hello " + name + "!");

Slide 80

Slide 80 text

public static void sayHi(java.lang.String); Code: 0: getstatic #2 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #3, 0 // InvokeDynamic #0:makeConcatWithConstants: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #4 // Method java/io/PrintStream.println:(…)V 14: return

Slide 81

Slide 81 text

public static void sayHi(java.lang.String); Code: 0: getstatic #2 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #3, 0 // InvokeDynamic #0:makeConcatWithConstants: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #4 // Method java/io/PrintStream.println:(…)V 14: return

Slide 82

Slide 82 text

public static void sayHi(java.lang.String); Code: 0: getstatic #2 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #3, 0 // InvokeDynamic #0:makeConcatWithConstants: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #4 // Method java/io/PrintStream.println:(…)V 14: return BootstrapMethods: 0: #19 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/MethodType;Ljava/lang/String; [Ljava/lang/Object;)Ljava/lang/invoke/CallSite; Method arguments: #20 Hey \u0001!\n Hola \u0001!\n Hello \u0001!

Slide 83

Slide 83 text

public static void sayHi(java.lang.String); Code: 0: getstatic #2 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #3, 0 // InvokeDynamic #0:makeConcatWithConstants: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #4 // Method java/io/PrintStream.println:(…)V 14: return BootstrapMethods: 0: #19 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/MethodType;Ljava/lang/String; [Ljava/lang/Object;)Ljava/lang/invoke/CallSite; Method arguments: #20 Hey \u0001!\n Hola \u0001!\n Hello \u0001!

Slide 84

Slide 84 text

System.out.println("" + "Hey " + name + "!\n" + " Hola " + name + "!\n" + " Hello " + name + "!");

Slide 85

Slide 85 text

System.out.println(""" Hey %s! Hola %s! Hello %s! """.formatted(name, name, name));

Slide 86

Slide 86 text

public static void sayHi(java.lang.String); Code: 0: getstatic #9 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #15, 0 // InvokeDynamic #0:format: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #19 // Method java/io/PrintStream.println:(…)V 14: return

Slide 87

Slide 87 text

public static void sayHi(java.lang.String); Code: 0: getstatic #9 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #15, 0 // InvokeDynamic #0:format: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #19 // Method java/io/PrintStream.println:(…)V 14: return

Slide 88

Slide 88 text

public static void sayHi(java.lang.String); Code: 0: getstatic #9 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #15, 0 // InvokeDynamic #0:format: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #19 // Method java/io/PrintStream.println:(…)V 14: return BootstrapMethods: 0: #34 REF_invokeStatic java/util/Formatter.formatterBootstrap: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/MethodType;Ljava/lang/String;II)… Method arguments: #41 Hey %s!\n Hola %s!\n Hello %s! #43 1 #44 0

Slide 89

Slide 89 text

public static void sayHi(java.lang.String); Code: 0: getstatic #9 // Field java/lang/System.out:… 3: aload_0 4: aload_0 5: aload_0 6: invokedynamic #15, 0 // InvokeDynamic #0:format: (Ljava/lang/String; Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String; 11: invokevirtual #19 // Method java/io/PrintStream.println:(…)V 14: return BootstrapMethods: 0: #34 REF_invokeStatic java/util/Formatter.formatterBootstrap: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/MethodType;Ljava/lang/String;II)… Method arguments: #41 Hey %s!\n Hola %s!\n Hello %s! #43 1 #44 0

Slide 90

Slide 90 text

System.out.println(""" Hey %s! Hola %s! Hello %s! """.formatted(name, name, name));

Slide 91

Slide 91 text

println(""" Hey $name! Hola $name! Hello $name! """.trimIndent()) System.out.println(""" Hey %s! Hola %s! Hello %s! """.formatted(name, name, name));

Slide 92

Slide 92 text

println(""" Hey $name! Hola $name! Hello $name! """.trimIndent()) System.out.println(""" Hey %s! Hola %s! Hello %s! """.formatted(name, name, name)); "Indify String Concatenation (StringConcatFactory)" youtrack.jetbrains.com/issue/KT-21147

Slide 93

Slide 93 text

Value-Based Classes

Slide 94

Slide 94 text

data class Person(val name: String, val age: Int)

Slide 95

Slide 95 text

data class Person(val name: String, val age: Int) record Person(String name, int age) { }

Slide 96

Slide 96 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 97

Slide 97 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 98

Slide 98 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 99

Slide 99 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 100

Slide 100 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 101

Slide 101 text

public java.lang.String getName(); public int getAge(); public java.lang.String toString(); Code: 0: new #44 // class java/lang/StringBuilder 3: dup 4: invokespecial #45 // Method java/lang/StringBuilder."":()V 7: ldc #47 // String Person(name= 9: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 12: aload_0 13: getfield #11 // Field name:Ljava/lang/String; 16: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: ldc #53 // String , age= 21: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: aload_0 25: getfield #19 // Field age:I 28: invokevirtual #56 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 31: ldc #58 // String ) 33: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 36: invokevirtual #60 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 39: areturn public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 102

Slide 102 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); Code: 0: aload_0 1: invokedynamic #19, 0 // InvokeDynamic #0:toString:(LPerson;)Ljava/lang/String; 6: areturn public int hashCode(); public boolean equals(java.lang.Object); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); Code: 0: new #44 // class java/lang/StringBuilder 3: dup 4: invokespecial #45 // Method java/lang/StringBuilder."":()V 7: ldc #47 // String Person(name= 9: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 12: aload_0 13: getfield #11 // Field name:Ljava/lang/String; 16: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: ldc #53 // String , age= 21: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: aload_0 25: getfield #19 // Field age:I 28: invokevirtual #56 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 31: ldc #58 // String ) 33: invokevirtual #51 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 36: invokevirtual #60 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 39: areturn public int hashCode();

Slide 103

Slide 103 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); Code: 0: aload_0 1: invokedynamic #19, 0 // InvokeDynamic #0:toString:(LPerson;)Ljava/lang/String; 6: areturn public int hashCode(); public boolean equals(java.lang.Object); }

Slide 104

Slide 104 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); Code: 0: aload_0 1: invokedynamic #19, 0 // InvokeDynamic #0:toString:(LPerson;)Ljava/lang/String; 6: areturn public int hashCode(); public boolean equals(java.lang.Object); } BootstrapMethods: 0: #42 REF_invokeStatic java/lang/runtime/ObjectMethods.bootstrap: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String; [Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object; Method arguments: #8 Person #49 name;age #51 REF_getField Person.name:Ljava/lang/String; #52 REF_getField Person.age:I Code: 0: aload_0 1: invokedynamic #23, 0 // InvokeDynamic #0:hashCode:(LPerson;)I 6: areturn

Slide 105

Slide 105 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); Code: 0: aload_0 1: invokedynamic #19, 0 // InvokeDynamic #0:toString:(LPerson;)Ljava/lang/String; 6: areturn public int hashCode(); public boolean equals(java.lang.Object); } BootstrapMethods: 0: #42 REF_invokeStatic java/lang/runtime/ObjectMethods.bootstrap: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String; [Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object; Method arguments: #8 Person #49 name;age #51 REF_getField Person.name:Ljava/lang/String; #52 REF_getField Person.age:I Code: 0: aload_0 1: invokedynamic #23, 0 // InvokeDynamic #0:hashCode:(LPerson;)I 6: areturn

Slide 106

Slide 106 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); Code: 0: aload_0 1: invokedynamic #23, 0 // InvokeDynamic #0:hashCode:(LPerson;)I 6: areturn public boolean equals(java.lang.Object); } BootstrapMethods: 0: #42 REF_invokeStatic java/lang/runtime/ObjectMethods.bootstrap: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String; [Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object; Method arguments: #8 Person #49 name;age #51 REF_getField Person.name:Ljava/lang/String; #52 REF_getField Person.age:I Code: 0: aload_0 1: invokedynamic #19, 0 // InvokeDynamic #0:toString:(LPerson;)Ljava/lang/String; 6: areturn

Slide 107

Slide 107 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); Code: 0: aload_0 1: invokedynamic #27, 0 // InvokeDynamic #0:equals:(LPerson;Ljava/lang/Object;)Z 6: areturn } BootstrapMethods: 0: #42 REF_invokeStatic java/lang/runtime/ObjectMethods.bootstrap: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String; Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String; [Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object; Method arguments: #8 Person #49 name;age #51 REF_getField Person.name:Ljava/lang/String; #52 REF_getField Person.age:I Code: 0: aload_0 1: invokedynamic #23, 0 // InvokeDynamic #0:hashCode:(LPerson;)I 6: areturn Code: 0: aload_0 1: invokedynamic #27, 0 /q InvokeDynamic #0:equals:(LPerson;Ljava/lang/Object;)Z 6: areturn

Slide 108

Slide 108 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… } public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); } Code: 0: aload_0 1: invokedynamic #27, 0 // InvokeDynamic #0:equals:(LPerson;Ljava/lang/Object;)Z 6: areturn

Slide 109

Slide 109 text

data class Person(val name: String, val age: Int) record Person(String name, int age) { }

Slide 110

Slide 110 text

data class Person(val name: String, val age: Int) record Person(String name, int age) { } "Use StringConcatFactory for data class toString when targeting JVM 9+ " youtrack.jetbrains.com/issue/KT-35176

Slide 111

Slide 111 text

Sealed Hierarchies

Slide 112

Slide 112 text

data class Person(val name: String, val age: Int)

Slide 113

Slide 113 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer()

Slide 114

Slide 114 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() record Person(String name, int age) { }

Slide 115

Slide 115 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Developer { } record Person(String name, int age) extends Developer { } record Business(String name) extends Developer { }

Slide 116

Slide 116 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() class extends extends sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { }

Slide 117

Slide 117 text

sealed class Developer { abstract val name: String } data class Person(override val name: String, val age: Int) : Developer() data class Business(override val name: String) : Developer() sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { }

Slide 118

Slide 118 text

sealed class Developer { abstract val name: String } data class Person(override val name: String, val age: Int) : Developer() data class Business(override val name: String) : Developer() sealed interface Developer { String name(); } record Person(@Override String name, int age) implements Developer { } record Business(@Override String name) implements Developer { }

Slide 119

Slide 119 text

public abstract class Developer { public abstract java.lang.String getName(); private Developer(); public synthetic Developer(kotlin.jvm.internal.DefaultConstructorMarker); } public interface Developer { public abstract java.lang.String name(); } PermittedSubtypes: Person Business

Slide 120

Slide 120 text

public abstract class Developer { public abstract java.lang.String getName(); private Developer(); public synthetic Developer(kotlin.jvm.internal.DefaultConstructorMarker); } public interface Developer { public abstract java.lang.String name(); } PermittedSubtypes: Person Business

Slide 121

Slide 121 text

public abstract class Developer { public abstract java.lang.String getName(); private Developer(); public synthetic Developer(kotlin.jvm.internal.DefaultConstructorMarker); } public interface Developer { public abstract java.lang.String name(); } PermittedSubtypes: Person Business

Slide 122

Slide 122 text

sealed class Developer { abstract val name: String } data class Person(override val name: String, val age: Int) : Developer() data class Business(override val name: String) : Developer() sealed interface Developer { String name(); } record Person(@Override String name, int age) implements Developer { } record Business(@Override String name) implements Developer { }

Slide 123

Slide 123 text

Type Matching

Slide 124

Slide 124 text

val o: Any = 1

Slide 125

Slide 125 text

val o: Any = 1 if (o is Int) { }

Slide 126

Slide 126 text

val o: Any = 1 if (o is Int) { println(o + 1) }

Slide 127

Slide 127 text

val o: Any = 1 if (o is Int) { println(o + 1) } Object o = 1; if (o instanceof Integer i) { System.out.println(i + 1); }

Slide 128

Slide 128 text

Object o = 1; if (o instanceof Integer i) { System.out.println(i + 1); }

Slide 129

Slide 129 text

Object o = 1; if (o instanceof Integer) { Integer i = (Integer) o; System.out.println(i + 1); }

Slide 130

Slide 130 text

Object o = 1; if (o instanceof Integer) { Integer i = (Integer) o; System.out.println(i + 1); } static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue(); }

Slide 131

Slide 131 text

Object o = 1; if (o instanceof Integer) { Integer i = (Integer) o; System.out.println(i + 1); record(o); } static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue(); }

Slide 132

Slide 132 text

Object o = 1; if (o instanceof Integer) { System.out.println(o + 1); record(o); } static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue(); }

Slide 133

Slide 133 text

Object o = 1; if (o instanceof Integer) { System.out.println(o + 1); record(o); } static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue(); }

Slide 134

Slide 134 text

Object o = 1; if (o instanceof Integer) { System.out.println(o + 1); record(o); } static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue(); }

Slide 135

Slide 135 text

Object o = 1; if (o instanceof Integer i) { System.out.println(i + 1); record(o); } static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue(); }

Slide 136

Slide 136 text

val o: Any = 1 if (o is Int) { println(o + 1) } Object o = 1; if (o instanceof Integer i) { System.out.println(i + 1); } record(o); static void record(Object o) { objects.add(o); } static void record(Number n) { sum += n.intValue();

Slide 137

Slide 137 text

Destructuring

Slide 138

Slide 138 text

data class Person(val name: String, val age: Int)

Slide 139

Slide 139 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12)

Slide 140

Slide 140 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice

Slide 141

Slide 141 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice val people = listOf(alice) for ((name, age) in people) { // .. }

Slide 142

Slide 142 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice val people = listOf(alice) for ((name, age) in people) { // .. } val display = people.map { (name, age) -> "$name is $age years old" }

Slide 143

Slide 143 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice

Slide 144

Slide 144 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice

Slide 145

Slide 145 text

⋮ 10: aload_0 11: invokevirtual #12 // Method Person.component1:()Ljava/lang/String; 14: astore_1 15: aload_0 16: invokevirtual #16 // Method Person.component2:()I 19: istore_2 ⋮

Slide 146

Slide 146 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy and component methods omitted… }

Slide 147

Slide 147 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy methods omitted… public java.lang.String component1(); public int component2(); } a n d c o m p o n e n t

Slide 148

Slide 148 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice

Slide 149

Slide 149 text

data class Person( val name: String, val nickname: String, val age: Int ) val alice = Person("Alice", "Ali", 12) val (name, age) = alice

Slide 150

Slide 150 text

public final class Person { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String getName(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy methods omitted… public java.lang.String component1(); public int component2(); }

Slide 151

Slide 151 text

public final class Person { private final java.lang.String name; + private final java.lang.String nickname; private final int age; - public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String getName(); + public java.lang.String getNickname(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy methods omitted… public java.lang.String component1(); - public int component2(); + public java.lang.String component2(); + public int component3(); }

Slide 152

Slide 152 text

public final class Person { private final java.lang.String name; + private final java.lang.String nickname; private final int age; - public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String getName(); + public java.lang.String getNickname(); public int getAge(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); // copy methods omitted… public java.lang.String component1(); - public int component2(); + public java.lang.String component2(); + public int component3(); }

Slide 153

Slide 153 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice

Slide 154

Slide 154 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice record Person(String name, int age) { } var alice = new Person("Alice", 12);

Slide 155

Slide 155 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice record Person(String name, int age) { } Object alice = new Person("Alice", 12);

Slide 156

Slide 156 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice record Person(String name, int age) { } Object alice = new Person("Alice", 12); if (alice instanceof Person alicePerson) { // ... }

Slide 157

Slide 157 text

data class Person(val name: String, val age: Int) val alice = Person("Alice", 12) val (name, age) = alice record Person(String name, int age) { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... } alicePerson

Slide 158

Slide 158 text

data class Person(val name: String, val age: Int) val alice: Any = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... } record Person(String name, int age) { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 159

Slide 159 text

record Person(String name, int age) { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 160

Slide 160 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); }

Slide 161

Slide 161 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); }

Slide 162

Slide 162 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); }

Slide 163

Slide 163 text

record Person(String name, int age) { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 164

Slide 164 text

record Person(String name, String nickname, int age) { } Object alice = new Person("Alice", "Ali", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 165

Slide 165 text

public final class Person extends java.lang.Record { private final java.lang.String name; private final int age; public Person(java.lang.String, int); public java.lang.String name(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); }

Slide 166

Slide 166 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; - public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); - public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); }

Slide 167

Slide 167 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; - public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); - public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); }

Slide 168

Slide 168 text

record Person(String name, String nickname, int age) { }

Slide 169

Slide 169 text

record Person(String name, String nickname, int age) { Person(String name, int age) { this(name, null, age); } }

Slide 170

Slide 170 text

record Person(String name, String nickname, int age) { Person(String name, int age) { this(name, null, age); } // WARNING: 100% made-up syntax by me! destructor Person(String, int) { return p -> deconstruct(Person::name, Person::age); } }

Slide 171

Slide 171 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; - public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); - public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); }

Slide 172

Slide 172 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); }

Slide 173

Slide 173 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); data class Person(val name: String, val age: Int) val alice: Any = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... } record Person(String name, int age) { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 174

Slide 174 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); sealed class Developer data class Person(val name: String, val age: Int): Developer() data class Business(val name: String): Developer() val alice: Any = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 175

Slide 175 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Object alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... } sealed class Developer data class Person(val name: String, val age: Int): Developer() data class Business(val name: String): Developer() val alice: Any = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... } public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString();

Slide 176

Slide 176 text

sealed class Developer data class Person(val name: String, val age: Int): Developer() data class Business(val name: String): Developer() val alice: Developer = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... } Object public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString();

Slide 177

Slide 177 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); sealed class Developer data class Person(val name: String, val age: Int): Developer() data class Business(val name: String): Developer() val alice: Developer = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... } Object

Slide 178

Slide 178 text

sealed class Developer data class Person(val name: String, val age: Int): Developer() data class Business(val name: String): Developer() val alice: Developer = Person("Alice", 12) if (alice is Person) { val (name, age) = alice // ... }

Slide 179

Slide 179 text

sealed class Developer data class Person(val name: String, val age: Int): Developer() data class Business(val name: String): Developer() val alice: Developer = Person("Alice", 12) when (alice) { is Person -> { val (name, age) = alice // ... } is Business -> { // ... } } if

Slide 180

Slide 180 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }

Slide 181

Slide 181 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... } if i n s t a n c e o f

Slide 182

Slide 182 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... }

Slide 183

Slide 183 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... }

Slide 184

Slide 184 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... }

Slide 185

Slide 185 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... }

Slide 186

Slide 186 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); public java.lang.String toString(); public int hashCode(); public boolean equals(java.lang.Object); public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?I)(); + public static java.lang.runtime.PatternHandle %pattern%Person%(Ljava|lang|String?Ljava|lang|String?I)(); } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... }

Slide 187

Slide 187 text

public final class Person extends java.lang.Record { private final java.lang.String name; + private final java.lang.String nickname; private final int age; public Person(java.lang.String, int); + public Person(java.lang.String, java.lang.String, int); public java.lang.String name(); + public java.lang.String nickname(); public int age(); val alice: Developer = Person("Alice", 12) when (alice) { is Person -> { val (name, age) = alice // ... } is Business -> // ... } Developer alice = new Person("Alice", 12); switch (alice) { case Person(var name, var age) -> // ... case Business b -> // ... } sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { }

Slide 188

Slide 188 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { }

Slide 189

Slide 189 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { }

Slide 190

Slide 190 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //...

Slide 191

Slide 191 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App) { }

Slide 192

Slide 192 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person) { }

Slide 193

Slide 193 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { }

Slide 194

Slide 194 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" }

Slide 195

Slide 195 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else if (download is Movie) { }

Slide 196

Slide 196 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else if (download is Movie && download.director.name == "Alice") { }

Slide 197

Slide 197 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else if (download is Movie && download.director.name == "Alice") { "Alice's movie ${download.title}" }

Slide 198

Slide 198 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else if (download is Movie && download.director.name == "Alice") { "Alice's movie ${download.title}" } else { "Not by Alice" }

Slide 199

Slide 199 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() data class TvShow(val title: String, val showRunner: Person) : Download() val download: Download = //... val result = if (download is App && download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else if (download is Movie && download.director.name == "Alice") { "Alice's movie ${download.title}" } else { "Not by Alice" }

Slide 200

Slide 200 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //...

Slide 201

Slide 201 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = when (download) { is App -> is Movie -> }

Slide 202

Slide 202 text

sealed class Developer data class Person(val name: String, val age: Int) : Developer() data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = when (download) { is App -> if (download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else { "Not by Alice" } is Movie -> }

Slide 203

Slide 203 text

data class Business(val name: String) : Developer() sealed class Download data class App(val name: String, val developer: Developer) : Download() data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = when (download) { is App -> if (download.developer is Person && download.developer.name == "Alice") { "Alice's app ${download.name}" } else { "Not by Alice" } is Movie -> if (download.director.name == "Alice") { "Alice's movie ${download.title}" } else { "Not by Alice" } }

Slide 204

Slide 204 text

data class Movie(val title: String, val director: Person) : Download() val download: Download = //... val result = when (download) { is App -> when (download.developer) { is Person -> if (download.developer.name == "Alice") { "Alice's app ${download.name}" } else { "Not by Alice" } else -> "Not by Alice" } is Movie -> if (download.director.name == "Alice") { "Alice's movie ${download.title}" } else { "Not by Alice" } }

Slide 205

Slide 205 text

val result = when (download) { is App -> { val (name, developer) = download when (developer) { is Person -> if (developer.name == "Alice") { "Alice's app $name" } else { "Not by Alice" } else -> "Not by Alice" } } is Movie -> { val (title, directory) = download if (director.name == "Alice") { "Alice's movie $title" } else { "Not by Alice" } } } download download download

Slide 206

Slide 206 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { }

Slide 207

Slide 207 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //...

Slide 208

Slide 208 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App -> case Movie -> };

Slide 209

Slide 209 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App -> case Movie -> };

Slide 210

Slide 210 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App -> case Movie -> };

Slide 211

Slide 211 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, var developer) -> case Movie -> };

Slide 212

Slide 212 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, var developer) -> case Movie -> };

Slide 213

Slide 213 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> case Movie -> }; var developer

Slide 214

Slide 214 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> case Movie -> }; var developer

Slide 215

Slide 215 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie -> };

Slide 216

Slide 216 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie(var title, Person("Alice", _)) -> };

Slide 217

Slide 217 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie(var title, Person("Alice", _)) -> "Alice's movie " + title };

Slide 218

Slide 218 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie(var title, Person("Alice", _)) -> "Alice's movie " + title case App(_), Movie(_) -> "Not by Alice" };

Slide 219

Slide 219 text

val download: Download = //... val result = when (download) { is App -> { val (name, developer) = download when (developer) { is Person -> if (developer.name == "Alice") { "Alice's app $name" } else { "Not by Alice" } else -> "Not by Alice" } } is Movie -> { val (title, directory) = download if (director.name == "Alice") { "Alice's movie $title" } else { "Not by Alice" } } } Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie(var title, Person("Alice", _)) -> "Alice's movie " + title case App(_), Movie(_) -> "Not by Alice" }; sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } sealed interface Download { } record App(String name, Developer developer) implements Download { } record Movie(String title, Person director) implements Download { }

Slide 220

Slide 220 text

Coroutines

Slide 221

Slide 221 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } }

Slide 222

Slide 222 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } } 
 
 
 
 
 
 
 
 
 
 0 1 2 3 4 5 6 7 8 9 10

Slide 223

Slide 223 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } }

Slide 224

Slide 224 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } }

Slide 225

Slide 225 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } }

Slide 226

Slide 226 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } } public static void main(String... args) { Executor e = Executors.newWorkStealingPool(); for (int count = 10; count >= 0; count--) { final var finalCount = count; e.execute(() -> { Thread.sleep(100 * finalCount); System.out.println(finalCount); }); } }

Slide 227

Slide 227 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } } public static void main(String... args) { Executor e = Executors.newWorkStealingPool(); for (int count = 10; count >= 0; count--) { final var finalCount = count; e.execute(() -> { Thread.sleep(100 * finalCount); System.out.println(finalCount); }); } }

Slide 228

Slide 228 text

suspend fun main() = coroutineScope { for (count in 10 downTo 0) { launch { delay(100.milliseconds * count) println(count) } } } public static void main(String... args) { Executor e = Executors.newWorkStealingPool(); for (int count = 10; count >= 0; count--) { final var finalCount = count; e.execute(() -> { Thread.sleep(100 * finalCount); System.out.println(finalCount); }); } }

Slide 229

Slide 229 text

The end of Kotlin?

Slide 230

Slide 230 text

var count = 1 final var users = new ArrayList() The end of Kotlin? Java 10: Variable Type Inference

Slide 231

Slide 231 text

public static boolean any(Predicate predicate) { var seen = new HashSet(); boolean hasMatch(Node node) { if (!seen.add(node)) return false; // already seen if (predicate.test(node)) return true; // match! return node.getNodes().stream().anyMatch(n -> hasMatch(n)); } return hasMatch(getRoot()); } Java 16/17: Local Methods

Slide 232

Slide 232 text

public static void main(String[] args) { System.out.println(""" SELECT * FROM users WHERE name LIKE 'Jake %' """); } Java 15: Multiline Strings

Slide 233

Slide 233 text

record Person(String name, int age) { } Java 15/16: Records

Slide 234

Slide 234 text

sealed interface Developer { } record Person(String name, int age) implements Developer { } record Business(String name) implements Developer { } Java 15/16: Sealed Hierarchies

Slide 235

Slide 235 text

Object o = 1; if (o instanceof Integer i) { System.out.println(i + 1); } Java 15/16: Type Matching

Slide 236

Slide 236 text

Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie(var title, Person("Alice", _)) -> "Alice's movie " + title case App(_), Movie(_) -> "Not by Alice" }; Java 16/17: Pattern Matching

Slide 237

Slide 237 text

Download download = //... var result = switch (download) { case App(var name, Person("Alice", _)) -> "Alice's app " + name case Movie(var title, Person("Alice", _)) -> "Alice's movie " + title case App(_), Movie(_) -> "Not by Alice" }; Java 14: Expression Switch

Slide 238

Slide 238 text

public static void main(String... args) { Executor e = Executors.newWorkStealingPool(); for (int count = 10; count >= 0; count--) { final var finalCount = count; e.execute(() -> { Thread.sleep(100 * finalCount); System.out.println(finalCount); }); } } Java 16/17: Virtual Threads

Slide 239

Slide 239 text

The end of Kotlin? New Java APIs and new VM improvements also help Kotlin

Slide 240

Slide 240 text

The end of Kotlin? New Java APIs and new VM improvements also help Kotlin API, bytecode, and VM changes for new Java language features are also available for use by kotlinc

Slide 241

Slide 241 text

The end of Kotlin? New Java APIs and new VM improvements also help Kotlin API, bytecode, and VM changes for new Java language features are also available for use by kotlinc No plans to tackle nullability in Java!

Slide 242

Slide 242 text

The end of Kotlin? New Java APIs and new VM improvements also help Kotlin API, bytecode, and VM changes for new Java language features are also available for use by kotlinc No plans to tackle nullability in Java! Java in 3 years will also be competing with Kotlin in 3 years,
 not the Kotlin of today

Slide 243

Slide 243 text

The end of Kotlin? New Java APIs and new VM improvements also help Kotlin API, bytecode, and VM changes for new Java language features are also available for use by kotlinc No plans to tackle nullability in Java! Java in 3 years will also be competing with Kotlin in 3 years,
 not the Kotlin of today Kotlin has an IDE to potentially evolve in ways that Java cannot

Slide 244

Slide 244 text

The end of Kotlin? New Java APIs and new VM improvements also help Kotlin API, bytecode, and VM changes for new Java language features are also available for use by kotlinc No plans to tackle nullability in Java! Java in 3 years will also be competing with Kotlin in 3 years,
 not the Kotlin of today Kotlin has an IDE to potentially evolve in ways that Java cannot Kotlin has first-class multiplatform

Slide 245

Slide 245 text

What's new in Java 19: The end of Kotlin? @JakeWharton [ Nope! ]