Pro Yearly is on sale from $80 to $50! »

How Kotlin implements features Java doesn't have

How Kotlin implements features Java doesn't have

CA.kt #1
TwitterID変えました。@lvla0805 -> @MoyuruAizawa

5f533179da1c82722252cbcb93e7356f?s=128

Moyuru Aizawa

June 15, 2017
Tweet

Transcript

  1. How Kotlin implements features Java doesn’t have @lvla0805

  2. Ѫᖒ๖ (Moyuru Aizawa) lvla lvla0805 - Kotlin engineer at CyberAgent,

    Inc. - FRESH!
  3. Data Classes Sealed Classes Extension Functions Inline Functions Default Arguments

    Named Arguments Delegation Properties Auto Casts Type Alias Covariance Null Safety Elvis Operator Spread Operator Operator Overloading Type Inference DSL Support Type-Safe Builders Coroutines String Interpolation Rages Map Array Syntax Destructuring KDoc
  4. None
  5. Bytecode

  6. NonNull / Nullable Extension Function Named Argument / Default Argument

  7. NonNull / Nullable

  8. fun nonNullInt(number: Int) { number.toString() } NonNull: Kotlin

  9. public final nonNullInt(I)V L0 LINENUMBER 7 L0 ILOAD 1 INVOKESTATIC

    java/lang/String.valueOf (I)Ljava/lang/String; POP … NonNull: Bytecode
  10. public final nonNullInt(I)V L0 LINENUMBER 7 L0 ILOAD 1 INVOKESTATIC

    java/lang/String.valueOf (I)Ljava/lang/String; POP … NonNull: Bytecode
  11. public final void nonNullInt(int number) { String.valueOf(number); } NonNull: Java

  12. fun nullableInt(number: Int?) { number?.toString() } Nullable: Kotlin

  13. public final nullableInt(Ljava/lang/Integer;)V @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0 L0 LINENUMBER

    7 L0 ALOAD 1 DUP IFNULL L1 INVOKEVIRTUAL java/lang/Integer.intValue ()I INVOKESTATIC java/lang/String.valueOf (I)Ljava/lang/String; POP GOTO L2 L1 POP … Nullable: Bytecode
  14. public final nullableInt(Ljava/lang/Integer;)V @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0 L0 LINENUMBER

    7 L0 ALOAD 1 DUP IFNULL L1 INVOKEVIRTUAL java/lang/Integer.intValue ()I INVOKESTATIC java/lang/String.valueOf (I)Ljava/lang/String; POP GOTO L2 L1 POP … Nullable: Bytecode
  15. public final nullableInt(Ljava/lang/Integer;)V @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0 L0 LINENUMBER

    7 L0 ALOAD 1 DUP IFNULL L1 INVOKEVIRTUAL java/lang/Integer.intValue ()I INVOKESTATIC java/lang/String.valueOf (I)Ljava/lang/String; POP GOTO L2 L1 POP … Nullable: Bytecode
  16. public final void nullableInt(@Nullable Integer number) { if(number != null)

    { String.valueOf(number.intValue()); } } Nullable: Java
  17. fun nonNullString(string: String) { string.length } NonNull: Kotlin

  18. public final nonNullString(Ljava/lang/String;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 ALOAD

    1 LDC "string" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 7 L1 ALOAD 1 INVOKEVIRTUAL java/lang/String.length ()I POP … NonNull: Bytecode
  19. public final nonNullString(Ljava/lang/String;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 ALOAD

    1 LDC "string" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 7 L1 ALOAD 1 INVOKEVIRTUAL java/lang/String.length ()I POP … NonNull
  20. public final nonNullString(Ljava/lang/String;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 ALOAD

    1 LDC "string" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 7 L1 ALOAD 1 INVOKEVIRTUAL java/lang/String.length ()I POP … NonNull: Bytecode
  21. public final void nonNullString(@NotNull String string) { Intrinsics.checkParameterIsNotNull(string, "string"); string.length();

    } NonNull: Java
  22. private fun nonNullString(string: String) { string.length } NonNull: Kotlin

  23. private final nonNullString(Ljava/lang/String;)V L0 LINENUMBER 7 L0 ALOAD 1 INVOKEVIRTUAL

    java/lang/String.length ()I POP NonNull: Bytecode
  24. private fun nullableString(string: String?) { string?.length } Nullable: Kotlin

  25. private final static nullableString(Ljava/lang/String;)V L0 LINENUMBER 2 L0 ALOAD 0

    DUP IFNULL L1 INVOKEVIRTUAL java/lang/String.length ()I POP GOTO L2 L1 POP L2 L3 LINENUMBER 3 L3 RETURN … Nullable: Bytecode
  26. private final void nullableString(String string) { if(string != null) {

    string.length(); } } Nullable: Java
  27. Conclusion of NonNull/Nullable Primitive NonNull -> Primitive Primitive Nullable ->

    BoxType ClassType NonNull -> ClassType, Check Null ClassType Nullable -> ClassType Safe Call -> IFNULL
  28. Extension Function

  29. fun String.println() { println(this) } "Hello World".println() // out: Hello

    World Extension Function
  30. Package Level Extension Function

  31. // in StringExtension.kt fun String.println() { println(this) } Package Level

    Extension Function: Kotlin
  32. public final class StringExtensionKt { public final static println(Ljava/lang/String;)V …

    } Package Level Extension Function: Bytecode
  33. public final class StringExtensionKt { public final static println(Ljava/lang/String;)V …

    } Package Level Extension Function: Bytecode
  34. public final class StringExtensionKt { public final static println(Ljava/lang/String;)V …

    } Package Level Extension Function: Bytecode
  35. public final class StringExtensionKt { public static final void println(@NotNull

    String $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); System.out.println($receiver); } } Package Level Extension Function: Java
  36. Class Level Extension Function

  37. class Foo { fun String.println() { println(this) } } Class

    Level Extension Function: Kotlin
  38. public final class Foo { public final println(Ljava/lang/String;)V … }

    Class Level Extension Function: Bytecode
  39. Extension Function Package Level Extension Function -> Static Method Class

    Level Extension Function -> Method
  40. Package Level Extension Function Package Level Extension Function -> Static

    Method
  41. Package Level Extension Function Public Package Level Extension Function ->

    Public Static Method Private Package Level Extension Function -> Private Static Method
  42. Scope of Package Level Extension Public Package Level Extension Function

    -> Anywhere Private Package Level Extension Function -> Same file
  43. Private Package Level Extension Function Private Package Level Extension Function

    -> Private Static Method
  44. // in Bar.kt private fun Foo.doSomething() { } class Foo

    { init { doSomething() } } Private Package Level Extension Function: Kotlin
  45. public final class FooKt { private final static doSomething(LFoo;)V …

    public final static synthetic access$doSomething(LFoo;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 LINENUMBER 1 L0 ALOAD 0 INVOKESTATIC FooKt.doSomething (LFoo;)V RETURN L1 LOCALVARIABLE $receiver LFoo; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 Private Package Level Extension Function: Bytecode
  46. public final class FooKt { private final static doSomething(LFoo;)V …

    public final static synthetic access$doSomething(LFoo;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 LINENUMBER 1 L0 ALOAD 0 INVOKESTATIC FooKt.doSomething (LFoo;)V RETURN L1 LOCALVARIABLE $receiver LFoo; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 Private Package Level Extension Function: Bytecode
  47. public final class FooKt { private final static doSomething(LFoo;)V …

    public final static synthetic access$doSomething(LFoo;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 LINENUMBER 1 L0 ALOAD 0 INVOKESTATIC FooKt.doSomething (LFoo;)V RETURN L1 LOCALVARIABLE $receiver LFoo; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 Private Package Level Extension Function: Bytecode
  48. Conclusion of Extension Function Package Level Extension Function -> Static

    Method Class Level Extension Function -> Method Call Private Package Level Extension Function from inside a class of same file -> Private Static Method and Accessor Method
  49. Named Argument Default Argument

  50. fun foo(one: String, two: String, three: String) { } foo(three

    = "tres", one = "uno", two = "dos") Named Argument: Kotlin
  51. LDC "tres" LDC "uno" LDC "dos" ASTORE 1 ASTORE 2

    ASTORE 3 ALOAD 2 ALOAD 1 ALOAD 3 INVOKEVIRTUAL Foo.foo (Ljava/lang/String;Ljava/lang/String;Ljava/lang/ String;)V Named Argument: Bytecode
  52. LDC "tres" LDC "uno" LDC "dos" ASTORE 1 ASTORE 2

    ASTORE 3 ALOAD 2 ALOAD 1 ALOAD 3 INVOKEVIRTUAL Foo.foo (Ljava/lang/String;Ljava/lang/String;Ljava/lang/ String;)V Named Argument: Bytecode
  53. LDC "tres" LDC "uno" LDC "dos" ASTORE 1 ASTORE 2

    ASTORE 3 ALOAD 2 ALOAD 1 ALOAD 3 INVOKEVIRTUAL Foo.foo (Ljava/lang/String;Ljava/lang/String;Ljava/lang/ String;)V Named Argument: Bytecode
  54. LDC "tres" LDC "uno" LDC "dos" ASTORE 1 ASTORE 2

    ASTORE 3 ALOAD 2 ALOAD 1 ALOAD 3 INVOKEVIRTUAL Foo.foo (Ljava/lang/String;Ljava/lang/String;Ljava/lang/ String;)V Named Argument: Bytecode
  55. String var1 = "dos"; String var2 = "uno"; String var3

    = "tres"; this.foo(var2, var1, var3); Named Argument: Java
  56. fun foo(one: String = “one", two: String = “two", three:

    String = "three") { } foo() foo("uno") foo("uno", "dos") foo("uno", "dos", "tres") foo(two = "dos") Default Argument: Kotlin
  57. fun foo(one: String = “one", two: String = “two", three:

    String = "three") { } foo(two = "dos") Default Argument: Kotlin
  58. ‣ public static void foo(String, String, String) ‣ public static

    void foo$default(String, String, String, int, Object) Default Argument: Java
  59. foo(two = "dos") Default Argument: Kotlin

  60. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  61. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  62. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  63. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  64. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  65. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  66. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  67. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 0 1 1
  68. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 101
  69. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java
  70. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java var1: null var2: “dos” var3: null
  71. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 101 001 101
 and 001 001 var1: null var2: “dos” var3: null
  72. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 101 001 101
 and 001 001 var1: “one” var2: “dos” var3: null
  73. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 101 010 101
 and 010 000 var1: “one” var2: “dos” var3: null
  74. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 101 100 101
 and 100 100 var1: “one” var2: “dos” var3: null
  75. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java 101 100 101
 and 100 100 var1: “one” var2: “dos” var3: “three”
  76. public static void foo$default( String var1, String var2, String var3,

    int var4, Object var5) { if((var4 & 1) != 0) { var1 = "one"; } if((var4 & 2) != 0) { var2 = "two"; } if((var4 & 4) != 0) { var3 = "three"; } foo(var1, var2, var3); } foo$default((String)null, "dos", (String)null, 5, (Object)null); Default Argument: Java “one”“dos”“three”
  77. Thank you