Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
プラットホーム型について ~Kotlinだって間違えるとnullでハマるよ!~
Search
RyotaMurohoshi
July 24, 2017
Technology
6
1.8k
プラットホーム型について ~Kotlinだって間違えるとnullでハマるよ!~
2017/07/24
『2017年7月定例会「Kotlin & Android Studio 3.0」』
の発表資料です
RyotaMurohoshi
July 24, 2017
Tweet
Share
More Decks by RyotaMurohoshi
See All by RyotaMurohoshi
Unityの合同同人誌や合同商業誌を書いてる僕は感想やレビューや評価が欲しい
ryotamurohoshi
0
170
Unity 2021.1での Unityパッケージの名称変更について
ryotamurohoshi
0
520
Odin Validationはいいぞ!
ryotamurohoshi
2
730
Tilemapはいいぞ!2020 〜すごいぞ、プロジェクト専用拡張Brush〜
ryotamurohoshi
0
2.2k
Unityでも、新しいC#
ryotamurohoshi
0
1.1k
Riderはいいぞ!
ryotamurohoshi
1
3k
Riderのススメ〜俺はRiderここが好き〜
ryotamurohoshi
1
2.1k
Unity開発者に伝えたい.NETのこと
ryotamurohoshi
4
33k
ImportedLinqのススメ
ryotamurohoshi
0
1.2k
Other Decks in Technology
See All in Technology
VS CodeでAWSを操作しよう
smt7174
7
1.6k
マルチアカウント環境への発見的統制の導入
ch1aki
1
1.3k
DevOpsメトリクスとアウトカムの接続にトライ!開発プロセスを通して計測できるメトリクスの活用方法
ham0215
2
230
Delivering Millions of Messages within seconds @ Duolingo
pelelgrino
0
350
反実仮想機械学習とは何か
usaito
PRO
11
3.8k
「スニダン」開発組織の構造に込めた意図 ~組織作りはパッションや政治ではない!~
rinchsan
3
540
APIファーストなプロダクトマネジメントの実践 〜SaaSus Platformでの例〜 / "Practicing API-First Product Management - An Example with SaaSus Platform
oztick139
0
100
長期運用プロジェクトでのMySQLからTiDB移行の検証
colopl
2
830
エンジニア候補者向け資料2024.04.24.pdf
macloud
0
3.3k
AWSに詳しくない人でも始められるコスト最適化ガイド
yuhta28
0
120
生産性向上チームの紹介
cybozuinsideout
PRO
1
860
複雑な構成要素を持つUIとの向き合い方 〜新・支出グラフでの実例〜 / B43 TECH TALK
nakamuuu
0
140
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
60
3.9k
WebSockets: Embracing the real-time Web
robhawkes
59
7k
We Have a Design System, Now What?
morganepeng
43
6.7k
Ruby is Unlike a Banana
tanoku
96
10k
Raft: Consensus for Rubyists
vanstee
132
6.3k
Building Applications with DynamoDB
mza
88
5.6k
Mobile First: as difficult as doing things right
swwweet
216
8.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
24
2k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
30
6k
The Cult of Friendly URLs
andyhume
74
5.7k
Facilitating Awesome Meetings
lara
42
5.6k
The Cost Of JavaScript in 2023
addyosmani
16
3.8k
Transcript
ϓϥοτϗʔϜܕʹ͍ͭͯ ~Kotlinͩͬͯؒҧ͑ΔͱnullͰϋϚΔΑʂ~ @RyotaMurohoshi 2017/07/24ʮKotlin-&-Android-Studio-3.0ʯ
Kotlinͷ͍͍ͱ͜Ζͱ͍͑ ԿΛࢥ͍ු͔·͔͢ʁ
ίʔυ͕؆ܿʹॻ͚Δͱ͜Ζʁ
Javaͱͷੑʁ
nullΛ͍͍ײ͡ʹѻ͑Δͱ͜Ζʁ
KotlinͷެࣜυΩϡϝϯτʹ ͜Μͳϖʔδ͋Γ·͢Ͷ
Null$Safety h"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ೖͰ͖Δ // OK val 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 { //
ུ } // ࣍OK val 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ܕͷมʹೖ͍ͯ͠Δ
͍ʂ
KotlinͰ NullPointerExcep/on ى͖·͢ʂ
͏গ͠ৄ͘͠ݴ͏ͱ
Javaͱͷڥք෦ͰదͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,onNullPointerExcep,on͕ൃੜ
Τϥʔ2ύλʔϯ
ύλʔϯͦͷ1 IllegalStateExcep,on͕ൃੜ
Javaͷίʔυ public class Reader { public static String readNullableStringJava() {
return null; } } Kotlinͷίʔυ // ͜ͷೖͨ͋ͨ͠ΓͰIllegalStateExceptionൃੜ val str : String = Reader.readNullableStringJava()
ύλʔϯ1 Java͔Β͖ͨnullΛKotlinͷStringܕͷมʹೖͨ࣌͠Ͱ IllegalStateExcep,on͕ൃੜ
ύλʔϯͦͷ2 NullPointerExcep/on͕ൃੜ
Javaͷίʔυ public class Reader { public static String readNullableStringJava() {
return null; } } Kotlinͷίʔυ // ͜ͷೖΛͨ͋ͨ͠ΓͰϥϯλΠϜΤϥʔൃੜ͠ͳ͍ val str = Reader.readNullableStringJava() // ͜͜ͰNullPointerExceptionͰࢮ͵ val length = str.length
ύλʔϯ2 Java͔Β͖ͨnullΛKotlinͰܕΛ໌ࣔతʹએݴ͠ͳ͍มʹೖ ͦͯ͠ϝϯόΞΫηεͨ࣌͠ͰNullPointerExcep/onͰࢮ͵
Javaͱͷڥք෦ͰదͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,onNullPointerExcep,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() // OK
println(str?.length) // ίϯύΠϧΤϥʔ println(str.length)
ͦͷ3ɹStringܕ // ԼStringܕ // ίϯύΠϧΤϥʔʹͳΒͳ͍ // ೖͨ͋ͨ͠ΓͰIllegalStateException͕ൃੜ val str: String
= Reader.readNullableStringJava() // ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δ println(str?.length) // OK println(str.length)
ϓϥοτϑΥʔϜܕΛ͔ͬ͠Γཧղʂ ಛʹܕΛ໌ࣔతʹએݴ͠ͳ͍Ͱ ϓϥοτϑΥʔϜܕͷ··ѻ͏߹ʹҙ
Javaͱͷڥք෦ͰదͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ௨Δ͚ΕͲ ࣮ߦ࣌ʹIllegalStateExcep,onNullPointerExcep,on͕ൃੜ
ͱΓ͋͑ͣString!ʢϓϥοτϑΥʔϜܕʣɺ String?Λ໌ࣔతʹએݴͨ͠มͰड͚͓͚ͯ ϥϯλΠϜΤϥʔൃੜ͠ͳ͍
ͱ͍͑
໌Β͔ʹnull͡Όͳ͍ͷ͋Δ ͍͍ͪͪString?Ͱड͚ΔͷΊΜͲ͍
͘͠Javaͷίʔυଆ͔Β String?Ͱड͚Δ͜ͱΛڧ੍͍ͨ͠
@NotNull'ͱ'@Nullable
Javaͷίʔυʹ@NotNullΛ͚ͭΔͱ KotlinͰTͱͯ͠ѻΘΕΔ @NotNull public static String readNotNull() { return "";
}
// IDE͕ɺฦΓܕStringͬͯڭ͑ͯ͘ΕΔʢString!Ͱͳ͍ʣ val str = Reader.readNotNull() // ͜ΕOK val str
: String = Reader.readNotNull() // ࣮ɺ͜ΕOK val str : String? = Reader.readNotNull()
Javaͷίʔυʹ@NullableΛ͚ͭΔͱ KotlinͰT?ͱͯ͠ѻΘΕΔ @Nulllable public static String readNullable() { return null;
}
// IDE͕ɺฦΓܕString?ͬͯڭ͑ͯ͘ΕΔʢString!Ͱͳ͍ʣ val str = Reader.readNullable() // ͜ΕOK val 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
ϙΠϯτ͓͞Β͍
ϙΠϯτ1 Javaͱͷڥք෦ͰదͳίʔυΛॻ͔ͳ͍ͱ ίϯύΠϧ௨Δ͚ΕͲ ࣮ߦ࣌ʹ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Ͱ NullPointerExcep/on ى͖·͢
Kotlin͕nullʹ·ͭΘΔΛ ͍͍ײ͡ʹղܾͰ͖Δ͚ΕͲ ͜ͷϙΠϯτΕͳ͍Ͱ͍ͩ͘͞
ʮnull҆શݴޠͬͯԿͰ͔͢Ͷʁʯ
ʮnull҆શݴޠʯͱ͍͏ݴ༿Λ ϒϩάSNSهࣄͰΘͳ͍Α͏ʹ͍ͯ͠·͢
• ੩తܕ͚ݴޠ • ΫϥεϕʔεͷΦϒδΣΫτࢦݴޠ • JVMݴޠ ͜͏͍͏ݴ༿ͱҧͬͯ໌֬ͳఆٛͱ͔ ڞ௨ೝࣝͱ͔͕ͦ͜·Ͱͳ͍ͱࢥ͏ΜͰ͢Α
͏࣌ͥͻɺఆٛΛॻ͍ͯΈ͍ͯͩ͘͞ ͦͯͦ͠ͷࡍɺϓϥοτϑΥʔϜܕʹ͍ͭͯʂ
͓·͚1 ϓϥοτϑΥʔϜܕؔ࿈ͷίʔυ IDEAͰɺTools)>)Kotlin)>)Show)Kotlin)Bytecode ͯ͠ɺDecompile͢Δͱ໘ന͍ͷͰΈͯΈ͍ͯͩ͘͞
͓·͚2 ϓϥοτϑΥʔϜܕҎ֎Ͱ ΠϯελϯεͷॳظԽؔ࿈Ͱ NullPointerExcep/on͕ൃੜ