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

What's new in Java 19: The end of Kotlin? (KotlinConf 2019)

Jake Wharton
December 06, 2019

What's new in Java 19: The end of Kotlin? (KotlinConf 2019)

Kotlin's introduction was a breath of fresh air at a time when the pace of innovation in Java felt glacial. Since that time, development of Java has rapidly increased with an emphasis on fixing the pain points of the language and the efficiency of data representation in the VM. Will Kotlin still have a place in the JVM language ecosystem in a few years?

This talk will compare and contrast how the two languages approach solving the same problems of today's Java. We'll look at data-carrying types, asynchronous programming, nullability, and more. For some of these, we'll also see how one language sometimes influenced the other. Finally, we'll peer a few years into the future to see where both languages are headed and determine whether we still need a Kotlin (spoiler: we probably do!).

Video: https://youtu.be/te3OU9fxC8U

Jake Wharton

December 06, 2019
Tweet

More Decks by Jake Wharton

Other Decks in Programming

Transcript

  1. var count = 1 val users = mutableListOf<String>() var count

    = 1 final var users = new ArrayList<String>()
  2. var count = 1 val users = mutableListOf<String>() var default:

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

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

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

    String? = null val tasks: Deque<Runnable> = ArrayDeque() var count = 1 final var users = new ArrayList<String>() String default = null Deque<Runnable> tasks = new ArrayDeque<>()
  6. val run1: () -> Unit = { /* .. */

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

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

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

    } val run2 = { /* .. */ } Runnable run1 = () -> { /* .. */ }; var run2 = new Runnable() { @Override public void run() { /* .. */ } };
  10. var count = 1 val users = mutableListOf<String>() var default:

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

    HashSet<Node>() 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() }
  12. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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() }
  13. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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() }
  14. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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() }
  15. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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() }
  16. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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<Node> predicate) { var seen = new HashSet<Node>(); 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()); }
  17. public static boolean any(Predicate<Node> predicate) { var seen = new

    HashSet<Node>(); 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()); }
  18. public static boolean any( Graph, java.util.function.Predicate<Node>); Code: 0: new #7

    // class java/util/HashSet 3: dup 4: invokespecial #9 // Method java/util/HashSet."<init>":()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: ...
  19. public static boolean any( Graph, java.util.function.Predicate<Node>); Code: 0: new #7

    // class java/util/HashSet 3: dup 4: invokespecial #9 // Method java/util/HashSet."<init>":()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: ...
  20. public static boolean any( Graph, java.util.function.Predicate<Node>); Code: 0: new #7

    // class java/util/HashSet 3: dup 4: invokespecial #9 // Method java/util/HashSet."<init>":()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: ...
  21. public static boolean any(Predicate<Node> predicate) { var seen = new

    HashSet<Node>(); 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()); }
  22. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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() }
  23. public static boolean any( Graph, kotlin.jvm.functions.Function1<Node, java.lang.Boolean>); Code: 0: new

    #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."<init>":()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."<init>": (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
  24. public static boolean any( Graph, kotlin.jvm.functions.Function1<Node, java.lang.Boolean>); Code: 0: new

    #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."<init>":()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."<init>": (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
  25. public static boolean any( Graph, kotlin.jvm.functions.Function1<Node, java.lang.Boolean>); Code: 0: new

    #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."<init>":()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."<init>": (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
  26. public static boolean any( Graph, kotlin.jvm.functions.Function1<Node, java.lang.Boolean>); Code: 0: new

    #20 // class java/util/HashSet 3: dup 4: invokespecial #24 // Method java/util/HashSet."<init>":()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."<init>": (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
  27. final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1<Node, java.lang.Boolean> { 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: ... }
  28. final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1<Node, java.lang.Boolean> { 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: ... }
  29. final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1<Node, java.lang.Boolean> { 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: ... }
  30. final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1<Node, java.lang.Boolean> { 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: ... }
  31. final class GraphKt$any$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1<Node, java.lang.Boolean> { 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: ... }
  32. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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() }
  33. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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
  34. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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
  35. fun Graph.any(predicate: (Node) -> Boolean): Boolean { val seen =

    HashSet<Node>() 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<Node> predicate) { var seen = new HashSet<Node>(); 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()); }
  36. fun main() { println(""" SELECT * FROM users WHERE name

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

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

    LIKE 'Jake %' !!!""".trimMargin(marginPrefix = "!!!")) } SELECT * FROM users WHERE name LIKE 'Jake %'
  39. 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 = " ! ! ! "
  40. 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 %' """); }
  41. public static void main(String[] args) { System.out.println(""" SELECT * FROM

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

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

    FROM users \ WHERE name LIKE 'Jake %' """); } SELECT * FROM users WHERE name LIKE 'Jake %'
  44. assertThat(table.toString()).isEqualTo(""" |┌─┬─┐ ╷ |│ │ │ │ |├─┤ ╵ │

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

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

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

    ····┌─┬─┐·╷ ····│·│·│·│ ····├─┤·╵·│ ····│·│···│ ····└─┼───┘ ······│···\s ····╶─┴─╴·\s ····""");
  48. 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."<init>":()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
  49. 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."<init>":()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
  50. 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."<init>":()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
  51. println(""" Hey $name! Hola $name! Hello $name! """.trimIndent()) System.out.println("" +

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

    Hola " + name + "!\n" + " Hello " + name + "!");
  53. 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
  54. 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
  55. 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!
  56. 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!
  57. System.out.println("" + "Hey " + name + "!\n" + "

    Hola " + name + "!\n" + " Hello " + name + "!");
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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); }
  64. 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); }
  65. 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); }
  66. 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); }
  67. 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); }
  68. 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."<init>":()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); }
  69. 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."<init>":()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();
  70. 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); }
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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
  76. 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
  77. sealed class Developer data class Person(val name: String, val age:

    Int) : Developer() data class Business(val name: String) : Developer()
  78. 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) { }
  79. 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 { }
  80. 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 { }
  81. 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 { }
  82. 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 { }
  83. 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
  84. 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
  85. 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
  86. 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 { }
  87. val o: Any = 1 if (o is Int) {

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

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

    i = (Integer) o; System.out.println(i + 1); }
  90. 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(); }
  91. 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(); }
  92. 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(); }
  93. 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(); }
  94. 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(); }
  95. 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(); }
  96. 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();
  97. data class Person(val name: String, val age: Int) val alice

    = Person("Alice", 12) val (name, age) = alice
  98. 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) { // .. }
  99. 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" }
  100. data class Person(val name: String, val age: Int) val alice

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

    = Person("Alice", 12) val (name, age) = alice
  102. ⋮ 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 ⋮
  103. 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… }
  104. 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
  105. data class Person(val name: String, val age: Int) val alice

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

    age: Int ) val alice = Person("Alice", "Ali", 12) val (name, age) = alice
  107. 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(); }
  108. 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(); }
  109. 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(); }
  110. data class Person(val name: String, val age: Int) val alice

    = Person("Alice", 12) val (name, age) = alice
  111. 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);
  112. 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);
  113. 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) { // ... }
  114. 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
  115. 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)) { // ... }
  116. record Person(String name, int age) { } Object alice =

    new Person("Alice", 12); if (alice instanceof Person(var name, var age)) { // ... }
  117. 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); }
  118. 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)(); }
  119. 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)(); }
  120. record Person(String name, int age) { } Object alice =

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

    alice = new Person("Alice", "Ali", 12); if (alice instanceof Person(var name, var age)) { // ... }
  122. 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)(); }
  123. 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)(); }
  124. 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)(); }
  125. 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); } }
  126. 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)(); }
  127. 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)(); }
  128. 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)) { // ... }
  129. 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)) { // ... }
  130. 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();
  131. 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();
  132. 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
  133. 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 // ... }
  134. 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
  135. 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)) { // ... }
  136. 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
  137. 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 -> // ... }
  138. 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 -> // ... }
  139. 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 -> // ... }
  140. 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 -> // ... }
  141. 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 -> // ... }
  142. 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 { }
  143. 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 { }
  144. 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 { }
  145. 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 = //...
  146. 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) { }
  147. 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) { }
  148. 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") { }
  149. 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}" }
  150. 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) { }
  151. 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") { }
  152. 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}" }
  153. 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" }
  154. 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" }
  155. 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 = //...
  156. 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 -> }
  157. 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 -> }
  158. 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" } }
  159. 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" } }
  160. 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
  161. 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 { }
  162. 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 = //...
  163. 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 -> };
  164. 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 -> };
  165. 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 -> };
  166. 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 -> };
  167. 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 -> };
  168. 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
  169. 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
  170. 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 -> };
  171. 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", _)) -> };
  172. 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 };
  173. 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" };
  174. 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 { }
  175. suspend fun main() = coroutineScope { for (count in 10

    downTo 0) { launch { delay(100.milliseconds * count) println(count) } } }
  176. 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
  177. suspend fun main() = coroutineScope { for (count in 10

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

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

    downTo 0) { launch { delay(100.milliseconds * count) println(count) } } }
  180. 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); }); } }
  181. 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); }); } }
  182. 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); }); } }
  183. var count = 1 final var users = new ArrayList<String>()

    The end of Kotlin? Java 10: Variable Type Inference
  184. public static boolean any(Predicate<Node> predicate) { var seen = new

    HashSet<Node>(); 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
  185. public static void main(String[] args) { System.out.println(""" SELECT * FROM

    users WHERE name LIKE 'Jake %' """); } Java 15: Multiline Strings
  186. sealed interface Developer { } record Person(String name, int age)

    implements Developer { } record Business(String name) implements Developer { } Java 15/16: Sealed Hierarchies
  187. Object o = 1; if (o instanceof Integer i) {

    System.out.println(i + 1); } Java 15/16: Type Matching
  188. 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
  189. 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
  190. 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
  191. The end of Kotlin? New Java APIs and new VM

    improvements also help Kotlin
  192. 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
  193. 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!
  194. 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
  195. 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
  196. 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