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

KotlinとJavaとnullのライトな話

RyotaMurohoshi
November 26, 2016

 KotlinとJavaとnullのライトな話

2016/11/26(土)のKotlin Internal勉強会の資料です

#kotlin_internal

https://connpass.com/event/40360/

RyotaMurohoshi

November 26, 2016
Tweet

More Decks by RyotaMurohoshi

Other Decks in Technology

Transcript

  1. KotlinͱJavaͱnullͷϥΠτͳ࿩
    @RyotaMurohoshi
    2016/11/26(౔)(Kotlin(internal(ษڧձ

    View Slide

  2. ͜Μͳ͜ͱ࿩͠·͢
    • nullʹ·ͭΘΔKotlinݴޠ࢓༷ͷ֬ೝ
    • όΠτίʔυͱσίϯύΠϧͨ͠Java͸Ͳ͏ͳΔʁ
    • ͪΐͬͱ͚ͩίϯύΠϥͷίʔυ΋ݟΔ

    View Slide

  3. ࣗݾ঺հ
    • ࣨ੕྄ଠ(ΉΖ΄͠)
    • @RyotaMurohoshi
    • ࢓ࣄͰKotlin+Android
    • झຯͰC#+UnityͰήʔϜ։ൃ

    View Slide

  4. ͱ͜ΖͰɺ࠷ۙ໨ʹͨ͠هࣄͱ͔

    View Slide

  5. ʰnull$ͱϓϩάϥϛϯάݴޠʱ

    View Slide

  6. ʰnull͕;ΜͪΌ͔ʱ

    View Slide

  7. ʰnull͕͋Δϓϩάϥϛϯάݴޠ͸
    ͳΜͪΌΒʱ

    View Slide

  8. ۤ͠ΜͰΔ͔ΒΈΜͳnullͷ࿩޷͖

    View Slide

  9. KotlinͷnullΛ͓͞Β͍

    View Slide

  10. String?Λฦؔ͢਺((Kotlinͷίʔυ)
    fun returnStringNullableKotlin(): String? = null

    View Slide

  11. ͜ΕΛ࢖͏ͱ!(Kotlinͷίʔυ)
    val str = returnNullableStringKotlin()
    // ͜Ε΋OK
    // val str : String? = returnNullableStringKotlin()
    // ͜Ε͸ίϯύΠϧΤϥʔ Type Mismatch
    // val str : String = returnNullableStringKotlin()
    // println(str.length) // ίϯύΠϧΤϥʔ
    println(str?.length) // ͜ΕͳΒOK

    View Slide

  12. ͞Α͏ͳΒnullʂʂʂ

    View Slide

  13. ຊ౰ʹʁ

    View Slide

  14. ݱ࣮͸ͦΜͳʹ؁͘ͳ͍

    View Slide

  15. Kotlin͚ͩͰίʔυΛॻ͖͖ΕΔΘ͚Ͱ͸ͳ͍
    ͦ͏ɺJavaͷίʔυΛݺͼग़͞ͳ͍ͱ͍͚ͳ͍
    ͦͷ৔߹null͸ɺNullable͸ʁ

    View Slide

  16. StringΛฦؔ͢਺'(Javaͷίʔυ)
    public class Utility {
    public static String returnNullableStringJava() {
    return null;
    }
    }

    View Slide

  17. ͜ΕΛ࢖͏ͱ!(JavaͷίʔυΛKotlinͷίʔυ͔ΒݺͿ)
    val str = Utility.returnNullableStringJava()
    // ͜Ε΋OK
    // val str : String? = Utility.returnNullableStringJava()
    // ஫໨ʂʂʂ
    // ͜Ε΋OKʂʂ ʂ
    // val str : String = Utility.returnNullableStringJava()

    View Slide

  18. JavaͰॻ͍ͨStringΛฦ͢ϝιουͷฦΓ஋͸ɺ
    Stringܕʹ΋String?ܕʹ΋୅ೖͰ͖Δ
    StringͱString?ͬͯҧ͏ܕͩͬͨ͸ͣͳͷʹʁ

    View Slide

  19. ʲ࠶ܝʳ͜ΕΛ࢖͏ͱ!(Kotlinͷίʔυ)
    val str = returnNullableStringKotlin()
    // ͜Ε΋OK
    // val str : String? = returnNullableStringKotlin()
    // ͜Ε͸ίϯύΠϧΤϥʔ Type Mismatch
    // val str : String = returnNullableStringKotlin()
    // println(str.length) // ίϯύΠϧΤϥʔ
    println(str?.length) // ͜ΕͳΒOK

    View Slide

  20. Pla$orm(Type
    U"lity.returnNullableStringJava()ͷฦΓ஋͸Pla6orm9Type

    View Slide

  21. • JavaͷࢀরܕͷϝιουͷฦΓ஋ͳͲ͸ɺPla'orm+Typeʹ
    • IDEͷ্Ͱ͸ɺString!ͱ͔Person!ͱ͔ͬͯද͢
    • ͚ͲίʔυͰɺString!ͱ͸ॻ͚ͳ͍

    View Slide

  22. ܕΛ໌ࣔతʹॻ͍ͨΒͲ͏ͳΔʁ

    View Slide

  23. U"lity.returnNullableStringJava()ͷฦΓ஋
    Stringܕʹ୅ೖͨ͠ΒҎޙɺStringܕͱͯ͠ѻ͏͠
    String?ܕʹ୅ೖͨ͠ΒҎޙɺString?ܕͱͯ͠ѻ͏

    View Slide

  24. JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    String?ʹ୅ೖ
    val str : String? = Utility.returnNullableStringJava()
    println(str?.length)
    // ίϯύΠϧΤϥʔ
    // println(str.length)

    View Slide

  25. JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    Stringʹ୅ೖ
    val str : String = Utility.returnNullableStringJava()
    println(str.length) // ίϯύΠϧΤϥʔʮͰ͸ʯͳ͍͚Ͳ
    // ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δ
    // println(str?.length)

    View Slide

  26. JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    ܕΛ໌ࣔ͠ͳ͍ͱ
    val str = Utility.returnNullableStringJava()
    // ͜Ε΋OK
    println(str?.length)
    // ͜Ε΋OKʁ(ίϯύΠϧΤϥʔʮͰ͸ʯͳ͍)
    println(str.length)

    View Slide

  27. ͳΔ΄ͲɺΊͰͨ͠ΊͰͨ͠ʁ

    View Slide

  28. ʹ͸ͳΒͳ͍
    ղઆΛޙճ͠ʹͨ͠఺͕ʮ2ͭʯʂ

    View Slide

  29. ʲ࠶ܝʳStringΛฦؔ͢਺'(Javaͷίʔυ)
    public class Utility {
    public static String returnNullableStringJava() {
    return null;
    }
    }

    View Slide

  30. ͍ͭ͜nullฦͧ͢ʂ

    View Slide

  31. JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    ܕΛ໌ࣔ͠ͳ͍ͱ
    val str = Utility.returnNullableStringJava()
    // ͜Ε΋OK
    println(str?.length)
    // ίϯύΠϧΤϥʔͰ͸ͳ͍͚ΕͲɺ
    // ࣮ߦ࣌ʹʮjava.lang.NullPointerExceptionʯ
    println(str.length)

    View Slide

  32. ͵ΔΆग़Δ͡ΌΜʂ
    Pla$orm(TypeͰ͸ɺʮNullPointerExcep5onʯͳ͛͏Δ

    View Slide

  33. ΋͏ͻͱͭ

    View Slide

  34. ʲ࠶ܝʳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    Stringʹ୅ೖ
    val str : String = Utility.returnNullableStringJava()
    println(str.length) // ίϯύΠϧΤϥʔʮͰ͸ʯͳ͍͚Ͳ
    // ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δ
    // println(str?.length)

    View Slide

  35. ͩΊͦ͏
    U"lity.returnNullableStringJava()͸nullΛฦ͢
    ͜ΕΛɺStringܕʹ୅ೖͯ͠
    ී௨ʹϝϯόʹΞΫηεͯ͠͠·͍ͬͯΔ

    View Slide

  36. ໰୊ɺͲ͏ͳΔʁ
    • ϝϯόʹΞΫηεͨ͠λΠϛϯάͰNullPointerExcep0on
    • ͦΕҎ֎ʢԿ͔ͷλΠϛϯάͰͳΜ͔ͷྫ֎Λ౤͛Δʣ

    View Slide

  37. ਖ਼ղ͸ɺʰͦΕҎ֎ʱ
    ϝϯόʹΞΫηε͢Δલʹྫ֎Λ౤͛Δ

    View Slide

  38. ʲ࠶ܝʳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    Stringʹ୅ೖ
    val str : String = Utility.returnNullableStringJava()
    println(str.length) // ίϯύΠϧΤϥʔʮͰ͸ʯͳ͍͚Ͳ
    ͜ͷίʔυΛ࣮ߦ͢Δͱ...

    View Slide

  39. java.lang.IllegalStateExcep0on
    Λ౤͛Δ
    U"lity.returnNullableStringJava()5must5not5be5null

    View Slide

  40. NullPointerExcep/onͰ͸ͳͯ͘IllegalStateExcep/on
    ͱ͍͏͜ͱ͸ɺίϯύΠϥ͕Կ͔͍ͯ͠Δ͸ͣʂ
    ݟͯΈΑ͏

    View Slide

  41. ʲ࠶ܝʳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    Stringʹ୅ೖ
    val str : String = Utility.returnNullableStringJava()
    println(str.length) // ίϯύΠϧΤϥʔʮͰ͸ʯͳ͍͚Ͳ
    ͜ͷByte%CodeΛΈͯΈΔ
    IDEAͰɺTools)>)Kotlin)>)Show)Kotlin)Bytecode

    View Slide

  42. L0
    LINENUMBER 73 L0
    INVOKESTATIC com/muhron/kotlin_java_interpolator/Utility.returnNullableStringJava ()Ljava/lang/String;
    DUP
    LDC "Utility.returnNullableStringJava()"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkExpressionValueIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
    ASTORE 0
    L1
    LINENUMBER 74 L1
    ALOAD 0
    INVOKEVIRTUAL java/lang/String.length ()I
    ISTORE 1
    NOP
    L2
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ILOAD 1
    INVOKEVIRTUAL java/io/PrintStream.println (I)V
    L3
    ͜ΕΛ͞ΒʹDecompoleʂ

    View Slide

  43. KotlinΛBytecodeʹͯ͠ɺͦΕΛ͞ΒʹDecompile
    String var10000 = Utility.returnNullableStringJava();
    Intrinsics.checkExpressionValueIsNotNull(var10000, "Utility.returnNullableStringJava()");
    String str = var10000;
    int var1 = str.length();
    System.out.println(var1);

    View Slide

  44. ϙΠϯτ͸
    ʮIntrinsics.checkExpressionValueIsNotNullʯ
    ϝϯόʹΞΫηε͢Δલʹɺ͜Ε͕ݺ͹Ε͍ͯΔʂ

    View Slide

  45. ίʔυΛݟͯΈ·͠ΐ͏ʂ
    Intrinsics.checkExpressionValueIsNotNull

    View Slide

  46. h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/core/run;me.jvm/src/kotlin/jvm/internal/
    Intrinsics.java#L86
    package kotlin.jvm.internal;
    @SuppressWarnings("unused")
    public class Intrinsics {
    private Intrinsics() {
    }
    /*ུ*/
    public static void checkExpressionValueIsNotNull(Object value, String expression) {
    if (value == null) {
    throw sanitizeStackTrace(new IllegalStateException(expression + " must not be null"));
    }
    }
    /*ུ*/
    }

    View Slide

  47. ͳΔ΄Ͳɺ͔֬ʹnullͩͬͨΒIllegalStateExcep.on౤͍͛ͯΔ

    View Slide

  48. Ͱ͸ɺ͜Ε͸୭͕Αͼ͍ͩͯ͠Δͷ͔ʁ
    ʮcheckExpressionValueIsNotNullʯͰ୳͢

    View Slide

  49. h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/compiler/backend/src/org/jetbrains/kotlin/codegen/
    AsmU?l.java#L650
    AsmU%lͱ͍͏தͰݺͼग़͍ͯ͠Δʂʂʂ
    ͞ΒʹಡΈਐΊΔͱ

    View Slide

  50. ExpressionCodegen#genQualified
    h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/compiler/backend/src/org/jetbrains/kotlin/codegen/
    ExpressionCodegen.java#L291
    ͱ
    Func%onCodegen#genDelegate
    h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/compiler/backend/src/org/jetbrains/kotlin/codegen/
    Func>onCodegen.java#L1029

    View Slide

  51. ͳΔ΄Ͳ

    View Slide

  52. ͯ͞ɺKotlinͰίʔυΛॻ͚Δͱݴͬͯ΋
    Javaͱͷ૬ޓӡ༻͸ඞਢʂ
    nullͱͷઓ͍͸ͭͮ͘ͷͰ͋ͬͨ

    View Slide

  53. ͚ͲͳΜͱ͔͍ͨ͠

    View Slide

  54. @NotNull
    ͱ
    @Nullable

    View Slide

  55. @NotNull

    View Slide

  56. Javaͷίʔυ
    // ΞϊςʔγϣϯΛ͚ͭΔ
    @NotNull
    public static String returnStringWithNotNullAnnotation() {
    return "";
    }

    View Slide

  57. @NotNullͳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    // IDE͸ɺฦΓ஋ܕ͕Stringͬͯڭ͑ͯ͘ΕΔʢString!Ͱ͸ͳ͍ʣ
    val str = Utility.returnStringWithNotNullAnnotation()
    // ͜Ε΋OK
    // val str : String = Utility.returnStringWithNotNullAnnotation()
    // ࣮͸ɺ͜Ε΋OK
    //val str : String? = Utility.returnStringWithNotNullAnnotation()
    println(str?.length) // ܯࠂ͕ͰΔ
    println(str.length) // ͜Ε͸OK

    View Slide

  58. @NotNullͳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    Bytecode()>(JavaͰίϯύΠϧ
    String str = Utility.returnStringWithNotNullAnnotation();
    int var1 = str.length();
    System.out.println(var1);

    View Slide

  59. @Nullable

    View Slide

  60. Javaͷίʔυ
    // ΞϊςʔγϣϯΛ͚ͭΔ
    @Nullable
    public static String returnStringWithNullableAnnotation() {
    return "";
    }

    View Slide

  61. @NullableͳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    // IDE͸ɺฦΓ஋ܕ͕String?ͬͯڭ͑ͯ͘ΕΔʢString!Ͱ͸ͳ͍ʣ
    val str = Utility.returnStringWithNullableAnnotation()
    // ͜Ε΋OK
    //val str : String? = Utility.returnNullableStringJava()
    // ͜Ε͸ίϯύΠϧΤϥʔ
    //val str : String = Utility.returnStringWithNullableAnnotation()
    println(str?.length) // ͜Ε͸OK
    // println(str.length) // ͜Ε͸ίϯύΠϧΤϥʔ

    View Slide

  62. @NullableͳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ
    Bytecode()>(JavaͰίϯύΠϧ
    String str = Utility.returnStringWithNullableAnnotation();
    Integer var1 = str != null?Integer.valueOf(str.length()):null;
    System.out.println(var1);

    View Slide

  63. ૬ޓӡ༻લఏͷJavaͷίʔυʹ͸ɺ
    @Nullabeͱ@NotNullΛ͚ͭΑ͏

    View Slide

  64. Androiderͷํɺ
    @Nullabeͱ͍͑͹ʁ

    View Slide

  65. LombokϢʔβʔͷํɺ
    @Nullableͱ͍͑͹ʁ

    View Slide

  66. FindbugsϢʔβʔͷํɺ
    @Nullableͱ͍͑͹ʁ

    View Slide

  67. JetBrainsతʹ
    @Nullabeͱ͍͑͹ʁ

    View Slide

  68. @NullableΊͬͪΌ͋Δʂʂʂ
    ͲͷNullableͩΑʂʁ

    View Slide

  69. ࣮͸ෳ਺ରԠ͍ͯ͠Δ
    • org.jetbrains.annota.ons.Nullable
    • android.support.annota.on.Nullable
    • com.android.annota.ons.Nullable
    • org.eclipse.jdt.annota.on.Nullable
    • org.checkerframework.checker.nullness.qual.Nullable
    h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/
    java/JvmAnnota?onNames.kt

    View Slide

  70. ࣮͸ෳ਺ରԠ͍ͯ͠Δʢଓ͖ʣ
    • javax.annota*on.Nullable
    • javax.annota*on.CheckForNull
    • edu.umd.cs.findbugs.annota*ons.CheckForNull
    • edu.umd.cs.findbugs.annota*ons.Nullable
    • edu.umd.cs.findbugs.annota*ons.PossiblyNull
    h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/
    java/JvmAnnota?onNames.kt

    View Slide

  71. ͜͜Β΁Μ΋OK

    View Slide

  72. ίʔυΛ௥͍·͠ΐ͏

    View Slide

  73. h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/
    java/JvmAnnota?onNames.kt
    val NULLABLE_ANNOTATIONS = listOf(
    JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION,
    FqName("android.support.annotation.Nullable"),
    FqName("com.android.annotations.Nullable"),
    FqName("org.eclipse.jdt.annotation.Nullable"),
    FqName("org.checkerframework.checker.nullness.qual.Nullable"),
    FqName("javax.annotation.Nullable"),
    FqName("javax.annotation.CheckForNull"),
    FqName("edu.umd.cs.findbugs.annotations.CheckForNull"),
    FqName("edu.umd.cs.findbugs.annotations.Nullable"),
    FqName("edu.umd.cs.findbugs.annotations.PossiblyNull")
    )

    View Slide

  74. typeQualifiers.ktͷதʹ....
    class JavaTypeQualifiers internal constructor(
    val nullability: NullabilityQualifier?,
    val mutability: MutabilityQualifier?,
    internal val isNotNullTypeParameter: Boolean
    ) {
    companion object {
    val NONE = JavaTypeQualifiers(null, null, false)
    }
    }
    ͷnullabilityͷੜ੒ʹ࢖ΘΕ͍ͯΔ
    h"ps:/
    /github.com/JetBrains/kotlin/blob/1.0.5/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/
    java/typeEnhancement/typeQualifiers.kt#L42

    View Slide

  75. ·ͱΊ
    • Pla%orm)TypeΛཧղ͠Α͏
    • Javaͱͷ૬ޓӡ༻ՕॴͰ͸ɺNullPointetExcep8on΍
    IllegalStateExcep8onՄೳੑ͋Γ
    • JavaͷϥΠϒϥϦʹ͸ɺ@Nullableͱ@NotNull͚ͭΑ͏

    View Slide

  76. NextΞΫγϣϯ
    ίϯύΠϥ͸ɺJavaTypeQualifiersΛ༻͍ͯ
    AsmU%l͕Intrinsicsݺͼग़͢ίʔυΛు͍͍ͯΔ
    ͱࢥΘΕΔͷͰɺௐࠪ

    View Slide

  77. ͋Γ͕ͱ͏͍͟͝·ͨ͠

    View Slide

  78. ؔ࿈ɾࢀߟ
    • Calling(Java(code(from(Kotlin
    h5ps:/
    /kotlinlang.org/docs/reference/java=interop.html
    • Kotlin(M9Ͱ௥Ճ͞ΕͨPlaAorm(Typeͷ࿩
    h5p:/
    /taro.hatenablog.jp/entry/2014/10/16/233702
    • ʲίʔυϦʔσΟϯάʳKotlin(to(JavaScriptίϯύΠϥϝϞ
    h5p:/
    /yyyank.blogspot.jp/2015/05/kotlinkotlin=to=
    javascript.html

    View Slide