2017/07/24
『2017年7月定例会「Kotlin & Android Studio 3.0」』
の発表資料です
ϓϥοτϗʔϜܕʹ͍ͭͯ~Kotlinͩͬͯؒҧ͑ΔͱnullͰϋϚΔΑʂ~@RyotaMurohoshi2017/07/24ʮKotlin-&-Android-Studio-3.0ʯ
View Slide
Kotlinͷ͍͍ͱ͜Ζͱ͍͑ԿΛࢥ͍ු͔·͔͢ʁ
ίʔυ͕؆ܿʹॻ͚Δͱ͜Ζʁ
Javaͱͷੑʁ
nullΛ͍͍ײ͡ʹѻ͑Δͱ͜Ζʁ
KotlinͷެࣜυΩϡϝϯτʹ͜Μͳϖʔδ͋Γ·͢Ͷ
Null$Safetyh"ps://kotlinlang.org/docs/reference/null6safety.html
ɹͱɾ͜ɾΖɾͰ
KotlinͩͬͨΒNullPointerExcep/on͕ى͖ͳ͍
ͬͯࢥ͍ͬͯ·ͤΜ͔ʁ
KotlinͰNullPointerExcep/onى͖·͢
KotlinͰNullPointerExcep/onى͖·͢ʂʂʂ
͚ΕͲKotlin͕ѱ͍Θ͚Ͱͳ͍͘ํ͕ؒҧ͍ͬͯΔͷͰ͢
• ࠷ۙKotlinΛ৮Γ࢝Ίͨ• Googleͷൃද͔ΒKotlinʹڵຯΛ࣋ͬͯ৮Γ࢝Ίͨ• ڈ͋ͨΓ͔ΒͳΜͱͳ͘Kotlinؾʹͳͬͯ৮Γ࢝Ίͨࠓ͜ͷΑ͏ͳํʹ͚ͯ
Android+KotlinΔ্ͰͲ͏͓͍͍͖͍ͯͬͯͯͨͩͨ͠ɺ
KotlinͱnullͱϓϥοτϗʔϜʹ͍ͭͯൃද͍͖ͤͯͨͩ͞·͢
͜Ε͔Β͓͢Δ͜ͱKotlinͷ͍͚ͯΔݴޠػೳͰAndroid+Kotlinͷ͍͚ͯΔϊϋͰ͋Γ·ͤΜ
͚ΕͲɺ͜Ε͔Β͓͢Δ͜ͱΛཧղ͢ΕόάΛੜΜͰ͠·͏͜ͱΛආ͚ΒΕΔ͔͠Ε·ͤΜ
ࣗݾհ
• @RyotaMurohoshi• ΉΖ΄͠• KotlinॿಡຊʹࢀՃ• ͔Θ͍͍Kotlinͱ͔Sansan༷ͷษڧձͰLT
Kotlinͱͷग़ձ͍@ngsw_taro͞Μͷ͋ΔΠϕϯτͰͷKotlinͱnullʹؔ͢ΔLTͰͨ͠
Kotlinͱnullجຊͷ͓͞Β͍
StringܕʹnullೖͰ͖ͳ͍// ίϯύΠϧΤϥʔval str: String = null
String?ܕͳΒnullೖͰ͖Δ// OKval str: String? = null
String͘͠nullΛฦ͢readMessageฦܕʮString?ʯܕʹ͢Δfun readMessage(): String? {// จࣈྻϦςϥϧΛฦ͔͢// nullΛฦ͔͢// ུ}
String͕null͔͠Εͳ͍ͱ͍͏ͱ͖String?ΛΘͳ͍ͱ͍͚ͳ͍
ͯ͞
StringܕʹString?ೖͰ͖ͳ͍// ࣍ͷؔ// StringϦςϥϧΛฦ͔͢͠Εͳ͍͠// nullΛฦ͔͢͠Εͳ͍fun readMessage(): String? {// ུ}// ίϯύΠϧΤϥʔval message: String = readMessage()
String?ܕʹStringೖͰ͖Δ// ࣍ͷؔ// StringΛฦ͢fun findTag(): String {// ུ}// ࣍OKval tag: String? = findTag()
nullʹ·ͭΘΔϥϯλΠϜΤϥʔΛආ͚ΔͨΊͷૉఢݴޠ༷
val message: String? = readMessage()// ࣍ίϯύΠϧΤϥʔ// String?ͰJavaΈ͍ͨͳॻ͖ํͰ͖ͳ͍val messageLength: Int = message.length// ࣍ίϯύΠϧΤϥʔʹͳΒͳ͍͕// message͕nullͳΒϥϯλΠϜΤϥʔval messageLength: Int = message!!.length// ࣍OK// messageLengthIntܕͰͳ͘Int?ܕval messageLength: Int? = message?.length
String?ܕͰJavaΈ͍ͨͳϝϯόΞΫηεͰ͖ͳ͍ݪଇɺʮ?.ʯΛ͏͘͠ϥϯλΠϜΤϥʔʹͳΔՄೳੑͷ͋Δʮ!!.ʯ
ͳΔ΄ͲNullPointerExcep/onൃੜ͠ͳͦ͏• StringܕʹnullೖͰ͖ͳ͍• null͔͠Εͳ͍ͱ͍͏࣌String?• StringͱString?ผ• String??.Ͱ
͚ΕͲɺ
KotlinͰNullPointerExcep/onى͖·͢ʂ
͔ͨ͠ʹKotlin͚ͩͰίʔυΛॻ͘ͷͳΒͦ͏ͦ͏NullPointerExcep/onൃੜ͠ͳ͍
ͦ͏ɺKotlin͚ͩͰॻ͘ͳΒ
օ͞Μ͕ࣗॻ͘ίʔυΛશͯKotlinʹ͢Δ͜ͱͰ͖ͦ͏Ͱ͢Ͷ
ͦ͏͍͑ɺࠓAndroidͷձͷΠϕϯτͰͨ͠Ͷ
ͱ͜ΖͰɺօ͞ΜAndroidΞϓϦ։ൃ
ϥΠϒϥϦ͍·͢ΑͶʁϑϨʔϜϫʔΫ͍·͢ΑͶʁ
Java
JavaʹString?ͱ͔ɺͳ͍
JavaͷίʔυΛݺͼग़͢Օॴཁҙʂ
͜ΜͳJavaͷίʔυΛKotlin͔Βݺͼग़ͨ͠ΒͲ͏ͳΔͩΖ͏ʁ// ͜ΕJavaͰ͢public class Reader {public static String readNullableStringJava() {return null;}}
Kotlin͔Βݺͼग़͢ͱɻɻɻ// ͜ΕίϯύΠϧΤϥʔʹͳΒͳ͍val str = Reader.readNullableStringJava()// ͜ΕίϯύΠϧΤϥʔʹͳΒͳ͍val str : String? = Reader.readNullableStringJava()// ʂ͜ΕίϯύΠϧΤϥʔʹͳΒͳ͍ʂʂʂval str : String = Reader.readNullableStringJava()
શ෦OKίϯύΠϧΤϥʔʹͳΒͳ͍
Ͱͪΐͬͱ͍ͬͯͩ͘͞
ʲ࠶ܝʳ͜ΜͳJavaͷίʔυΛKotlin͔Βݺͼग़ͨ͠ΒͲ͏ͳΔͩΖ͏ʁ// ͜ΕJavaͰ͢public class Reader {public static String readNullableStringJava() {return null;}}
ʲ࠶ܝʳKotlin͔Βݺͼग़͢ͱɻɻɻ// ͜ΕίϯύΠϧΤϥʔʹͳΒͳ͍val str = Reader.readNullableStringJava()// ͜ΕίϯύΠϧΤϥʔʹͳΒͳ͍val str : String? = Reader.readNullableStringJava()// ʂ͜ΕίϯύΠϧΤϥʔʹͳΒͳ͍ʂʂʂval str : String = Reader.readNullableStringJava()
nullΛString?͡Όͳͯ͘Stringܕͷมʹೖ͍ͯ͠Δ
͍ʂ
͏গ͠ৄ͘͠ݴ͏ͱ
Javaͱͷڥք෦ͰదͳίʔυΛॻ͔ͳ͍ͱίϯύΠϧ௨Δ͚ΕͲ࣮ߦ࣌ʹIllegalStateExcep,onNullPointerExcep,on͕ൃੜ
Τϥʔ2ύλʔϯ
ύλʔϯͦͷ1IllegalStateExcep,on͕ൃੜ
Javaͷίʔυpublic class Reader {public static String readNullableStringJava() {return null;}}Kotlinͷίʔυ// ͜ͷೖͨ͋ͨ͠ΓͰIllegalStateExceptionൃੜval str : String = Reader.readNullableStringJava()
ύλʔϯ1Java͔Β͖ͨnullΛKotlinͷStringܕͷมʹೖͨ࣌͠ͰIllegalStateExcep,on͕ൃੜ
ύλʔϯͦͷ2NullPointerExcep/on͕ൃੜ
Javaͷίʔυpublic class Reader {public static String readNullableStringJava() {return null;}}Kotlinͷίʔυ// ͜ͷೖΛͨ͋ͨ͠ΓͰϥϯλΠϜΤϥʔൃੜ͠ͳ͍val str = Reader.readNullableStringJava()// ͜͜ͰNullPointerExceptionͰࢮ͵val length = str.length
ύλʔϯ2Java͔Β͖ͨnullΛKotlinͰܕΛ໌ࣔతʹએݴ͠ͳ͍มʹೖͦͯ͠ϝϯόΞΫηεͨ࣌͠ͰNullPointerExcep/onͰࢮ͵
ͲͬͪJava͔Βདྷͨnull͕ݪҼJavaͷString͕KotlinͷString?͡Όͳ͍͔Β͜͏͍͏͜ͱʹ
ϙΠϯτϓϥοτϗʔϜܕʂ
JavaͰͷࢀরܕKotlinͰಛผѻ͍͞ΕΔ͜Ε͕ϓϥοτϗʔϜܕ
ϓϥοτϗʔϜܕ• IDEͱ͔ͰString!ͱ͔ͬͯද͞ΕΔͭ• ίʔυ্ͰɺܕΛ໌ࣔతʹString!ͱॻ͚ͳ͍• String!StringʹString?ʹೖͰ͖Δ• ਪ͞ΕͯString!ͰѻΘΕΔ߹͕͋Δ
Kotlin͔ΒݟΔͱฦܕϓϥοτϑΥʔϜܕͷString!public class Reader {public static String readNullableStringJava() {return null;}}
Kotlin͔Βݺͼग़͢ͱɻɻɻ// ԼͷstrϓϥοτϗʔϜܕͷString!// ͚ͲString!ͬͯ໌ࣔతʹॻ͚ͳ͍val str = Reader.readNullableStringJava()// String?ܕͷมʹೖval str : String? = Reader.readNullableStringJava()// Stringܕͷมʹೖval str : String = Reader.readNullableStringJava()
• String!ܕ(໌ࣔతʹॻ͔ͣਪ͞ΕΔ)• String?ܕ(໌ࣔతʹએݴ)• Stringܕ(໌ࣔతʹએݴ)ͦΕͧΕͷ߹Ͳ͏ͳΔʁ
ͦͷ1"String!ܕ(ϓϥοτϑΥʔϜܕ)// ԼϓϥοτϑΥʔϜܕͷString!val str = Reader.readNullableStringJava()// ίϯύΠϧΤϥʔͰͳ͍͠ɺ࣮ߦ࣌ΤϥʔʹͳΒͳ͍println(str?.length)// ίϯύΠϧΤϥʔʮͰʯͳ͍͚Ͳɺ// ࣮ߦ࣌ʹNullPointerExceptionൃੜprintln(str.length)
ͦͷ2ɹString?ܕ// ԼStringܕval str: String? = Reader.readNullableStringJava()// OKprintln(str?.length)// ίϯύΠϧΤϥʔprintln(str.length)
ͦͷ3ɹStringܕ// ԼStringܕ// ίϯύΠϧΤϥʔʹͳΒͳ͍// ೖͨ͋ͨ͠ΓͰIllegalStateException͕ൃੜval str: String = Reader.readNullableStringJava()// ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δprintln(str?.length)// OKprintln(str.length)
ϓϥοτϑΥʔϜܕΛ͔ͬ͠ΓཧղʂಛʹܕΛ໌ࣔతʹએݴ͠ͳ͍ͰϓϥοτϑΥʔϜܕͷ··ѻ͏߹ʹҙ
ͱΓ͋͑ͣString!ʢϓϥοτϑΥʔϜܕʣɺString?Λ໌ࣔతʹએݴͨ͠มͰड͚͓͚ͯϥϯλΠϜΤϥʔൃੜ͠ͳ͍
ͱ͍͑
໌Β͔ʹnull͡Όͳ͍ͷ͋Δ͍͍ͪͪString?Ͱड͚ΔͷΊΜͲ͍
͘͠Javaͷίʔυଆ͔ΒString?Ͱड͚Δ͜ͱΛڧ੍͍ͨ͠
@NotNull'ͱ'@Nullable
Javaͷίʔυʹ@NotNullΛ͚ͭΔͱKotlinͰTͱͯ͠ѻΘΕΔ@NotNullpublic static String readNotNull() {return "";}
// IDE͕ɺฦΓܕStringͬͯڭ͑ͯ͘ΕΔʢString!Ͱͳ͍ʣval str = Reader.readNotNull()// ͜ΕOKval str : String = Reader.readNotNull()// ࣮ɺ͜ΕOKval str : String? = Reader.readNotNull()
Javaͷίʔυʹ@NullableΛ͚ͭΔͱKotlinͰT?ͱͯ͠ѻΘΕΔ@Nulllablepublic static String readNullable() {return null;}
// IDE͕ɺฦΓܕString?ͬͯڭ͑ͯ͘ΕΔʢString!Ͱͳ͍ʣval str = Reader.readNullable()// ͜ΕOKval str : String? = Reader.readNullable()// ͜ΕίϯύΠϧΤϥʔval str : String = Reader.readNullable()
͋͠ͳ͕ͨJavaͷϥΠϒϥϦΛॻ͍͍ͯΔͳΒͥͻ@NotNullͱ@NullableΛదʹ͚ͭͯΈ͍ͯͩ͘͞h"ps://kotlinlang.org/docs/reference/java7interop.html#nullability7annota=ons
ͪͳΈʹ࣮ෳରԠ͍ͯ͠Δ• 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
ϙΠϯτ͓͞Β͍
ϙΠϯτ1Javaͱͷڥք෦ͰదͳίʔυΛॻ͔ͳ͍ͱίϯύΠϧ௨Δ͚ΕͲ࣮ߦ࣌ʹIllegalStateExcep,onNullPointerExcep,on͕ൃੜ
ϙΠϯτ2ϓϥοτϑΥʔϜܕΛ͔ͬ͠ΓཧղʂಛʹܕΛ໌ࣔతʹએݴ͠ͳ͍ͰϓϥοτϑΥʔϜܕͷ··ѻ͏߹ʹҙ
ϙΠϯτ3͋͠ͳ͕ͨJavaͷϥΠϒϥϦΛॻ͍͍ͯΔͳΒͥͻ@NotNullͱ@NullableΛదʹ͚ͭͯΈ͍ͯͩ͘͞
Kotlin͍͍ݴޠͰ͢
Kotlinେ͖Ͱ͢
ࠓͷඪɺKotlinΛ࠷ۙ࢝Ίͨਓ͕ʮKotlinͰNullPointerExcep0onͰΔ͡ΌΜʔʂʯͱ͍͏ࣄނΛ͙͜ͱͰͨ͠
ʮKotlinͩͬͯؒҧ͑ΔͱnullͰϋϚΔʂʯ͜Ε͕1݅ͰݮΕ͏Ε͍͠Ͱ͢
͔͜͜Βઌ༨ஊͰ͢
ʮKotlinΛͻΖΊͯߦ͜͏ʂʯͬͯਓɺ͍ͯͩ͘͠͞
ʮnull$safetyͬͯԿͰ͔͢Ͷʁʯ
KotlinͰNullPointerExcep0onൃੜ͠·͢!!ͦ͏ͩ͠ɺॳظԽλΠϛϯάͰൃੜ͢Δ͜ͱ͋Δ
ʮnull$safetyʯNullPointerExcep/on͕ൃੜ͠ͳ͍͜ͱͰͳͯ͘
nullΛѻ͍͍͢ݴޠ༷ɾػೳʹΑΓNullPointerExcep/on͕ൃੜͮ͠Β͍͜ͱͩͱࢥ͍ͬͯ·͢
Kotlin͕nullʹ·ͭΘΔΛ͍͍ײ͡ʹղܾͰ͖Δ͚ΕͲ͜ͷϙΠϯτΕͳ͍Ͱ͍ͩ͘͞
ʮnull҆શݴޠͬͯԿͰ͔͢Ͷʁʯ
ʮnull҆શݴޠʯͱ͍͏ݴ༿ΛϒϩάSNSهࣄͰΘͳ͍Α͏ʹ͍ͯ͠·͢
• ੩తܕ͚ݴޠ• ΫϥεϕʔεͷΦϒδΣΫτࢦݴޠ• JVMݴޠ͜͏͍͏ݴ༿ͱҧͬͯ໌֬ͳఆٛͱ͔ڞ௨ೝࣝͱ͔͕ͦ͜·Ͱͳ͍ͱࢥ͏ΜͰ͢Α
͏࣌ͥͻɺఆٛΛॻ͍ͯΈ͍ͯͩͦͯͦ͘͞͠ͷࡍɺϓϥοτϑΥʔϜܕʹ͍ͭͯʂ
͓·͚1ϓϥοτϑΥʔϜܕؔ࿈ͷίʔυIDEAͰɺTools)>)Kotlin)>)Show)Kotlin)Bytecodeͯ͠ɺDecompile͢Δͱ໘ന͍ͷͰΈͯΈ͍ͯͩ͘͞
͓·͚2ϓϥοτϑΥʔϜܕҎ֎ͰΠϯελϯεͷॳظԽؔ࿈ͰNullPointerExcep/on͕ൃੜ