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

プラットホーム型について ~Kotlinだって間違えるとnullでハマるよ!~

プラットホーム型について ~Kotlinだって間違えるとnullでハマるよ!~

2017/07/24

『2017年7月定例会「Kotlin & Android Studio 3.0」』

の発表資料です

F46c97bb74758d481531990654933050?s=128

RyotaMurohoshi

July 24, 2017
Tweet

Transcript

  1. ϓϥοτϗʔϜܕʹ͍ͭͯ ~Kotlinͩͬͯؒҧ͑ΔͱnullͰϋϚΔΑʂ~ @RyotaMurohoshi 2017/07/24ʮKotlin-&-Android-Studio-3.0ʯ

  2. Kotlinͷ͍͍ͱ͜Ζͱ͍͑͹ ԿΛࢥ͍ු͔΂·͔͢ʁ

  3. ίʔυ͕؆ܿʹॻ͚Δͱ͜Ζʁ

  4. Javaͱͷ਌࿨ੑʁ

  5. nullΛ͍͍ײ͡ʹѻ͑Δͱ͜Ζʁ

  6. KotlinͷެࣜυΩϡϝϯτʹ͸ ͜Μͳϖʔδ΋͋Γ·͢Ͷ

  7. Null$Safety h"ps:/ /kotlinlang.org/docs/reference/null6safety.html

  8. ɹͱɾ͜ɾΖɾͰ

  9. KotlinͩͬͨΒ NullPointerExcep/on ͕ى͖ͳ͍

  10. ͬͯࢥ͍ͬͯ·ͤΜ͔ʁ

  11. KotlinͰ΋ NullPointerExcep/on ى͖·͢

  12. KotlinͰ΋ NullPointerExcep/on ى͖·͢ʂʂʂ

  13. ͚ΕͲKotlin͕ѱ͍Θ͚Ͱ͸ͳ͘ ࢖͍ํ͕ؒҧ͍ͬͯΔͷͰ͢

  14. • ࠷ۙKotlinΛ৮Γ࢝Ίͨ • Googleͷൃද͔ΒKotlinʹڵຯΛ࣋ͬͯ৮Γ࢝Ίͨ • ڈ೥͋ͨΓ͔ΒͳΜͱͳ͘Kotlinؾʹͳͬͯ৮Γ࢝Ίͨ ࠓ೔͸͜ͷΑ͏ͳํʹ޲͚ͯ

  15. Android+Kotlin΍Δ্Ͱ Ͳ͏ͯ͠΋஌͓͍͍͖͍ͬͯͯͨͩͨɺ

  16. KotlinͱnullͱϓϥοτϗʔϜʹ͍ͭͯ ൃද͍͖ͤͯͨͩ͞·͢

  17. ͜Ε͔Β͓࿩͢Δ͜ͱ͸ Kotlinͷ͍͚ͯΔݴޠػೳͰ΋ Android+Kotlinͷ͍͚ͯΔϊ΢ϋ΢Ͱ΋͋Γ·ͤΜ

  18. ͚ΕͲɺ͜Ε͔Β͓࿩͢Δ͜ͱΛཧղ͢Ε͹ όάΛੜΜͰ͠·͏͜ͱΛආ͚ΒΕΔ͔΋͠Ε·ͤΜ

  19. ࣗݾ঺հ

  20. • @RyotaMurohoshi • ΉΖ΄͠ • Kotlinॿ૸ಡຊʹࢀՃ • ͔Θ͍͍Kotlinͱ͔Sansan༷ͷษڧձͰLT

  21. Kotlinͱͷग़ձ͍͸ @ngsw_taro͞Μͷ͋ΔΠϕϯτͰͷ Kotlinͱnullʹؔ͢ΔLTͰͨ͠

  22. Kotlinͱnull جຊͷ͓͞Β͍

  23. Stringܕʹnull͸୅ೖͰ͖ͳ͍ // ίϯύΠϧΤϥʔ val str: String = null

  24. String?ܕͳΒ͹null͸୅ೖͰ͖Δ // OK val str: String? = null

  25. String΋͘͠͸nullΛฦ͢readMessage ฦ஋ܕ͸ʮString?ʯܕʹ͢Δ fun readMessage(): String? { // จࣈྻϦςϥϧΛฦ͔͢΋ // nullΛฦ͔͢΋

    // ུ }
  26. String͕null͔΋͠Εͳ͍ ͱ͍͏ͱ͖͸String?Λ ࢖Θͳ͍ͱ͍͚ͳ͍

  27. ͯ͞

  28. StringܕʹString?͸୅ೖͰ͖ͳ͍ // ࣍ͷؔ਺͸ // StringϦςϥϧΛฦ͔͢΋͠Εͳ͍͠ // nullΛฦ͔͢΋͠Εͳ͍ fun readMessage(): String?

    { // ུ } // ίϯύΠϧΤϥʔ val message: String = readMessage()
  29. String?ܕʹString͸୅ೖͰ͖Δ // ࣍ͷؔ਺͸ // StringΛฦ͢ fun findTag(): String { //

    ུ } // ࣍͸OK val tag: String? = findTag()
  30. nullʹ·ͭΘΔϥϯλΠϜΤϥʔΛ ආ͚ΔͨΊͷૉఢݴޠ࢓༷

  31. val message: String? = readMessage() // ࣍͸ίϯύΠϧΤϥʔ // String?ͰJavaΈ͍ͨͳॻ͖ํ͸Ͱ͖ͳ͍ val

    messageLength: Int = message.length // ࣍͸ίϯύΠϧΤϥʔʹ͸ͳΒͳ͍͕ // message͕nullͳΒ͹ϥϯλΠϜΤϥʔ val messageLength: Int = message!!.length // ࣍͸OK // messageLength͸IntܕͰͳ͘Int?ܕ val messageLength: Int? = message?.length
  32. String?ܕͰ͸JavaΈ͍ͨͳ ϝϯόΞΫηε͸Ͱ͖ͳ͍ ݪଇɺʮ?.ʯΛ࢖͏ ΋͘͠͸ϥϯλΠϜΤϥʔʹͳΔՄೳੑͷ͋Δʮ!!.ʯ

  33. ͳΔ΄ͲNullPointerExcep/onൃੜ͠ͳͦ͏ • Stringܕʹnull͸୅ೖͰ͖ͳ͍ • null͔΋͠Εͳ͍ͱ͍͏࣌͸String? • StringͱString?͸ผ • String?͸?.Ͱ

  34. ͚ΕͲɺ

  35. KotlinͰ΋ NullPointerExcep/on ى͖·͢ʂ

  36. ͔ͨ͠ʹ Kotlin͚ͩͰίʔυΛॻ͘ͷͳΒ͹ ͦ͏ͦ͏NullPointerExcep/on͸ൃੜ͠ͳ͍

  37. ͦ͏ɺKotlin͚ͩͰॻ͘ͳΒ

  38. օ͞Μࣗ਎͕ॻ͘ίʔυΛશͯ Kotlinʹ͢Δ͜ͱ͸Ͱ͖ͦ͏Ͱ͢Ͷ

  39. ͦ͏͍͑͹ɺࠓ೔͸AndroidͷձͷΠϕϯτͰͨ͠Ͷ

  40. ͱ͜ΖͰɺօ͞ΜAndroidΞϓϦ։ൃ

  41. ϥΠϒϥϦ࢖͍·͢ΑͶʁ ϑϨʔϜϫʔΫ࢖͍·͢ΑͶʁ

  42. Java

  43. JavaʹString?ͱ͔ɺͳ͍

  44. JavaͷίʔυΛݺͼग़͢Օॴ ཁ஫ҙʂ

  45. ͜ΜͳJavaͷίʔυΛ Kotlin͔Βݺͼग़ͨ͠ΒͲ͏ͳΔͩΖ͏ʁ // ͜Ε͸JavaͰ͢ public class Reader { public static

    String readNullableStringJava() { return null; } }
  46. Kotlin͔Βݺͼग़͢ͱɻɻɻ // ͜Ε͸ίϯύΠϧΤϥʔʹͳΒͳ͍ val str = Reader.readNullableStringJava() // ͜Ε΋ίϯύΠϧΤϥʔʹͳΒͳ͍ val

    str : String? = Reader.readNullableStringJava() // ஫໨ʂ͜Ε΋ίϯύΠϧΤϥʔʹͳΒͳ͍ʂʂʂ val str : String = Reader.readNullableStringJava()
  47. શ෦OK ίϯύΠϧΤϥʔʹͳΒͳ͍

  48. Ͱ΋ͪΐͬͱ଴͍ͬͯͩ͘͞

  49. ʲ࠶ܝʳ͜ΜͳJavaͷίʔυΛ Kotlin͔Βݺͼग़ͨ͠ΒͲ͏ͳΔͩΖ͏ʁ // ͜Ε͸JavaͰ͢ public class Reader { public static

    String readNullableStringJava() { return null; } }
  50. ʲ࠶ܝʳKotlin͔Βݺͼग़͢ͱɻɻɻ // ͜Ε͸ίϯύΠϧΤϥʔʹͳΒͳ͍ val str = Reader.readNullableStringJava() // ͜Ε΋ίϯύΠϧΤϥʔʹͳΒͳ͍ val

    str : String? = Reader.readNullableStringJava() // ஫໨ʂ͜Ε΋ίϯύΠϧΤϥʔʹͳΒͳ͍ʂʂʂ val str : String = Reader.readNullableStringJava()
  51. nullΛString?͡Όͳͯ͘ Stringܕͷม਺ʹ୅ೖ͍ͯ͠Δ

  52. ΍͹͍ʂ

  53. KotlinͰ΋ NullPointerExcep/on ى͖·͢ʂ

  54. ΋͏গ͠ৄ͘͠ݴ͏ͱ

  55. Javaͱͷڥք෦Ͱద੾ͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ͸௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,on΍NullPointerExcep,on͕ൃੜ

  56. Τϥʔ͸2ύλʔϯ

  57. ύλʔϯͦͷ1 IllegalStateExcep,on͕ൃੜ

  58. Javaͷίʔυ public class Reader { public static String readNullableStringJava() {

    return null; } } Kotlinͷίʔυ // ͜ͷ୅ೖͨ͋ͨ͠ΓͰIllegalStateExceptionൃੜ val str : String = Reader.readNullableStringJava()
  59. ύλʔϯ1͸ Java͔Β͖ͨnullΛKotlinͷStringܕͷม਺ʹ୅ೖͨ࣌͠఺Ͱ IllegalStateExcep,on͕ൃੜ

  60. ύλʔϯͦͷ2 NullPointerExcep/on͕ൃੜ

  61. Javaͷίʔυ public class Reader { public static String readNullableStringJava() {

    return null; } } Kotlinͷίʔυ // ͜ͷ୅ೖΛͨ͋ͨ͠ΓͰ͸ϥϯλΠϜΤϥʔ͸ൃੜ͠ͳ͍ val str = Reader.readNullableStringJava() // ͜͜ͰNullPointerExceptionͰࢮ͵ val length = str.length
  62. ύλʔϯ2͸ Java͔Β͖ͨnullΛKotlinͰܕΛ໌ࣔతʹએݴ͠ͳ͍ม਺ʹ୅ೖ ͦͯ͠ϝϯόΞΫηεͨ࣌͠఺ͰNullPointerExcep/onͰࢮ͵

  63. Javaͱͷڥք෦Ͱద੾ͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ͸௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,on΍NullPointerExcep,on͕ൃੜ

  64. Ͳͬͪ΋Java͔Βདྷͨnull͕ݪҼ JavaͷString͕KotlinͷString?͡Όͳ͍ ͔Β͜͏͍͏͜ͱʹ

  65. ϙΠϯτ͸ϓϥοτϗʔϜܕʂ

  66. JavaͰͷࢀরܕ͸KotlinͰ͸ಛผѻ͍͞ΕΔ ͜Ε͕ϓϥοτϗʔϜܕ

  67. ϓϥοτϗʔϜܕ͸ • IDEͱ͔ͰString!ͱ͔ͬͯද͞ΕΔ΍ͭ • ίʔυ্Ͱ͸ɺܕΛ໌ࣔతʹString!ͱ͸ॻ͚ͳ͍ • String!͸Stringʹ΋String?ʹ΋୅ೖͰ͖Δ • ਪ࿦͞ΕͯString!ͰѻΘΕΔ৔߹͕͋Δ

  68. Kotlin͔ΒݟΔͱฦ஋ܕ͸ ϓϥοτϑΥʔϜܕͷString! public class Reader { public static String readNullableStringJava()

    { return null; } }
  69. Kotlin͔Βݺͼग़͢ͱɻɻɻ // Լͷstr͸ϓϥοτϗʔϜܕͷString! // ͚ͲString!ͬͯ໌ࣔతʹ͸ॻ͚ͳ͍ val str = Reader.readNullableStringJava() //

    String?ܕͷม਺ʹ୅ೖ val str : String? = Reader.readNullableStringJava() // Stringܕͷม਺ʹ୅ೖ val str : String = Reader.readNullableStringJava()
  70. • String!ܕ(໌ࣔతʹॻ͔ͣਪ࿦͞ΕΔ) • String?ܕ(໌ࣔతʹએݴ) • Stringܕ(໌ࣔతʹએݴ) ͦΕͧΕͷ৔߹Ͳ͏ͳΔʁ

  71. ͦͷ1"String!ܕ(ϓϥοτϑΥʔϜܕ) // Լ͸ϓϥοτϑΥʔϜܕͷString! val str = Reader.readNullableStringJava() // ίϯύΠϧΤϥʔͰͳ͍͠ɺ࣮ߦ࣌Τϥʔʹ΋ͳΒͳ͍ println(str?.length)

    // ίϯύΠϧΤϥʔʮͰ͸ʯͳ͍͚Ͳɺ // ࣮ߦ࣌ʹNullPointerExceptionൃੜ println(str.length)
  72. ͦͷ2ɹString?ܕ // Լ͸Stringܕ val str: String? = Reader.readNullableStringJava() // OK

    println(str?.length) // ίϯύΠϧΤϥʔ println(str.length)
  73. ͦͷ3ɹStringܕ // Լ͸Stringܕ // ίϯύΠϧΤϥʔʹ͸ͳΒͳ͍ // ୅ೖͨ͋ͨ͠ΓͰIllegalStateException͕ൃੜ val str: String

    = Reader.readNullableStringJava() // ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δ println(str?.length) // OK println(str.length)
  74. ϓϥοτϑΥʔϜܕΛ͔ͬ͠Γཧղʂ ಛʹܕΛ໌ࣔతʹએݴ͠ͳ͍Ͱ ϓϥοτϑΥʔϜܕͷ··ѻ͏৔߹ʹ஫ҙ

  75. Javaͱͷڥք෦Ͱద੾ͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ͸௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,on΍NullPointerExcep,on͕ൃੜ

  76. ͱΓ͋͑ͣString!ʢϓϥοτϑΥʔϜܕʣ͸ɺ String?Λ໌ࣔతʹએݴͨ͠ม਺Ͱड͚͓͚ͯ͹ ϥϯλΠϜΤϥʔ͸ൃੜ͠ͳ͍

  77. ͱ͸͍͑

  78. ໌Β͔ʹnull͡Όͳ͍΋ͷ΋͋Δ ͍͍ͪͪString?Ͱड͚ΔͷΊΜͲ͍

  79. ΋͘͠͸Javaͷίʔυଆ͔Β String?Ͱड͚Δ͜ͱΛڧ੍͍ͨ͠

  80. @NotNull'ͱ'@Nullable

  81. Javaͷίʔυʹ@NotNullΛ͚ͭΔͱ KotlinͰTͱͯ͠ѻΘΕΔ @NotNull public static String readNotNull() { return "";

    }
  82. // IDE͕ɺฦΓ஋ܕ͸Stringͬͯڭ͑ͯ͘ΕΔʢString!Ͱ͸ͳ͍ʣ val str = Reader.readNotNull() // ͜Ε΋OK val str

    : String = Reader.readNotNull() // ࣮͸ɺ͜Ε΋OK val str : String? = Reader.readNotNull()
  83. Javaͷίʔυʹ@NullableΛ͚ͭΔͱ KotlinͰT?ͱͯ͠ѻΘΕΔ @Nulllable public static String readNullable() { return null;

    }
  84. // IDE͕ɺฦΓ஋ܕ͸String?ͬͯڭ͑ͯ͘ΕΔʢString!Ͱ͸ͳ͍ʣ val str = Reader.readNullable() // ͜Ε΋OK val str

    : String? = Reader.readNullable() // ͜Ε͸ίϯύΠϧΤϥʔ val str : String = Reader.readNullable()
  85. ΋͋͠ͳ͕ͨJavaͷϥΠϒϥϦΛॻ͍͍ͯΔͳΒ͹ ͥͻ@NotNullͱ@NullableΛద੾ʹ͚ͭͯΈ͍ͯͩ͘͞ h"ps:/ /kotlinlang.org/docs/reference/java7interop.html#nullability7annota=ons

  86. ͪͳΈʹ࣮͸ෳ਺ରԠ͍ͯ͠Δ • android.support.annota-on.Nullable • com.android.annota-ons.Nullable • org.eclipse.jdt.annota-on.Nullable • org.checkerframework.checker.nullness.qual.Nullable •

    org.jetbrains.annota-ons.Nullable
  87. ϙΠϯτ͓͞Β͍

  88. ϙΠϯτ1 Javaͱͷڥք෦Ͱద੾ͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ͸௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,on΍NullPointerExcep,on͕ൃੜ

  89. ϙΠϯτ2 ϓϥοτϑΥʔϜܕΛ͔ͬ͠Γཧղʂ ಛʹܕΛ໌ࣔతʹએݴ͠ͳ͍Ͱ ϓϥοτϑΥʔϜܕͷ··ѻ͏৔߹ʹ஫ҙ

  90. ϙΠϯτ3 ΋͋͠ͳ͕ͨJavaͷϥΠϒϥϦΛॻ͍͍ͯΔͳΒ͹ ͥͻ@NotNullͱ@NullableΛద੾ʹ͚ͭͯΈ͍ͯͩ͘͞

  91. Kotlin͸͍͍ݴޠͰ͢

  92. Kotlinେ޷͖Ͱ͢

  93. ࠓ೔ͷ໨ඪ͸ɺKotlinΛ࠷ۙ࢝Ίͨਓ͕ ʮKotlinͰ΋NullPointerExcep0onͰΔ͡ΌΜʔʂʯ ͱ͍͏ࣄނΛ๷͙͜ͱͰͨ͠

  94. ʮKotlinͩͬͯؒҧ͑ΔͱnullͰϋϚΔʂʯ ͜Ε͕1݅Ͱ΋ݮΕ͹͏Ε͍͠Ͱ͢

  95. ͔͜͜Βઌ͸༨ஊͰ͢

  96. ʮKotlinΛͻΖΊͯߦ͜͏ʂʯ ͬͯਓɺ஫໨͍ͯͩ͘͠͞

  97. ʮnull$safetyͬͯԿͰ͔͢Ͷʁʯ

  98. KotlinͰ΋NullPointerExcep0on ͸ൃੜ͠·͢ !!΋ͦ͏ͩ͠ɺॳظԽλΠϛϯάͰൃੜ͢Δ͜ͱ΋͋Δ

  99. ๻͸ʮnull$safetyʯ͸ NullPointerExcep/on͕ൃੜ͠ͳ͍͜ͱ Ͱ͸ͳͯ͘

  100. nullΛѻ͍΍͍͢ݴޠ࢓༷ɾػೳʹΑΓ NullPointerExcep/on͕ൃੜͮ͠Β͍ ͜ͱͩͱࢥ͍ͬͯ·͢

  101. KotlinͰ΋ NullPointerExcep/on ى͖·͢

  102. Kotlin͕nullʹ·ͭΘΔ໰୊Λ ͍͍ײ͡ʹղܾͰ͖Δ͚ΕͲ ͜ͷϙΠϯτ͸๨Εͳ͍Ͱ͍ͩ͘͞

  103. ʮnull҆શݴޠͬͯԿͰ͔͢Ͷʁʯ

  104. ๻͸ʮnull҆શݴޠʯͱ͍͏ݴ༿Λ ϒϩά΍SNS΍هࣄͰ࢖Θͳ͍Α͏ʹ͍ͯ͠·͢

  105. • ੩తܕ෇͚ݴޠ • ΫϥεϕʔεͷΦϒδΣΫτࢦ޲ݴޠ • JVMݴޠ ͜͏͍͏ݴ༿ͱҧͬͯ໌֬ͳఆٛͱ͔ ڞ௨ೝࣝͱ͔͕ͦ͜·Ͱͳ͍ͱࢥ͏ΜͰ͢Α

  106. ࢖͏࣌͸ͥͻɺఆٛΛॻ͍ͯΈ͍ͯͩ͘͞ ͦͯͦ͠ͷࡍ͸ɺϓϥοτϑΥʔϜܕʹ͍ͭͯ΋ʂ

  107. ͓·͚1 ϓϥοτϑΥʔϜܕؔ࿈ͷίʔυ IDEAͰɺTools)>)Kotlin)>)Show)Kotlin)Bytecode ͯ͠ɺDecompile͢Δͱ໘ന͍ͷͰΈͯΈ͍ͯͩ͘͞

  108. ͓·͚2 ϓϥοτϑΥʔϜܕҎ֎Ͱ΋ ΠϯελϯεͷॳظԽؔ࿈Ͱ NullPointerExcep/on͕ൃੜ