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とJavaとnullのライトな話
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
RyotaMurohoshi
November 26, 2016
Technology
2
1.7k
KotlinとJavaとnullのライトな話
2016/11/26(土)のKotlin Internal勉強会の資料です
#kotlin_internal
https://connpass.com/event/40360/
RyotaMurohoshi
November 26, 2016
Tweet
Share
More Decks by RyotaMurohoshi
See All by RyotaMurohoshi
Tilemapのアップデートについて
ryotamurohoshi
0
61
Unityの合同同人誌や合同商業誌を書いてる僕は感想やレビューや評価が欲しい
ryotamurohoshi
0
570
Unity 2021.1での Unityパッケージの名称変更について
ryotamurohoshi
0
780
Odin Validationはいいぞ!
ryotamurohoshi
2
1k
Tilemapはいいぞ!2020 〜すごいぞ、プロジェクト専用拡張Brush〜
ryotamurohoshi
0
2.4k
Unityでも、新しいC#
ryotamurohoshi
0
1.4k
Riderはいいぞ!
ryotamurohoshi
1
3.7k
Riderのススメ〜俺はRiderここが好き〜
ryotamurohoshi
1
2.6k
Unity開発者に伝えたい.NETのこと
ryotamurohoshi
4
38k
Other Decks in Technology
See All in Technology
(金融庁共催)第4回金融データ活用チャレンジ勉強会資料
takumimukaiyama
0
120
分析画面のクリック操作をそのままコード化 ! エンジニアとビジネスユーザーが共存するAI-ReadyなBI基盤
ikumi
0
170
セキュリティについて学ぶ会 / 2026 01 25 Takamatsu WordPress Meetup
rocketmartue
1
270
しろおびセキュリティへ ようこそ
log0417
0
290
生成AI時代にこそ求められるSRE / SRE for Gen AI era
ymotongpoo
5
2.4k
Azure Durable Functions で作った NL2SQL Agent の精度向上に取り組んだ話/jat08
thara0402
0
130
Agile Leadership Summit Keynote 2026
m_seki
1
260
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
320
日本語テキストと音楽の対照学習の技術とその応用
lycorptech_jp
PRO
1
410
使いにくいの壁を突破する
sansantech
PRO
1
110
AI時代、1年目エンジニアの悩み
jin4
1
160
コスト削減から「セキュリティと利便性」を担うプラットフォームへ
sansantech
PRO
3
1.1k
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
The untapped power of vector embeddings
frankvandijk
1
1.6k
The browser strikes back
jonoalderson
0
360
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Thoughts on Productivity
jonyablonski
74
5k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
300
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
120
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
170
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Transcript
KotlinͱJavaͱnullͷϥΠτͳ @RyotaMurohoshi 2016/11/26()(Kotlin(internal(ษڧձ
͜Μͳ͜ͱ͠·͢ • nullʹ·ͭΘΔKotlinݴޠ༷ͷ֬ೝ • όΠτίʔυͱσίϯύΠϧͨ͠JavaͲ͏ͳΔʁ • ͪΐͬͱ͚ͩίϯύΠϥͷίʔυݟΔ
ࣗݾհ • ྄ࣨଠ(ΉΖ΄͠) • @RyotaMurohoshi • ࣄͰKotlin+Android • झຯͰC#+UnityͰήʔϜ։ൃ
ͱ͜ΖͰɺ࠷ۙʹͨ͠هࣄͱ͔
ʰnull$ͱϓϩάϥϛϯάݴޠʱ
ʰnull͕;ΜͪΌ͔ʱ
ʰnull͕͋Δϓϩάϥϛϯάݴޠ ͳΜͪΌΒʱ
ۤ͠ΜͰΔ͔ΒΈΜͳnullͷ͖
KotlinͷnullΛ͓͞Β͍
String?Λฦؔ͢((Kotlinͷίʔυ) fun returnStringNullableKotlin(): String? = null
͜ΕΛ͏ͱ!(Kotlinͷίʔυ) val str = returnNullableStringKotlin() // ͜ΕOK // val str
: String? = returnNullableStringKotlin() // ͜ΕίϯύΠϧΤϥʔ Type Mismatch // val str : String = returnNullableStringKotlin() // println(str.length) // ίϯύΠϧΤϥʔ println(str?.length) // ͜ΕͳΒOK
͞Α͏ͳΒnullʂʂʂ
ຊʹʁ
ݱ࣮ͦΜͳʹ͘ͳ͍
Kotlin͚ͩͰίʔυΛॻ͖͖ΕΔΘ͚Ͱͳ͍ ͦ͏ɺJavaͷίʔυΛݺͼग़͞ͳ͍ͱ͍͚ͳ͍ ͦͷ߹nullɺNullableʁ
StringΛฦؔ͢'(Javaͷίʔυ) public class Utility { public static String returnNullableStringJava() {
return null; } }
͜ΕΛ͏ͱ!(JavaͷίʔυΛKotlinͷίʔυ͔ΒݺͿ) val str = Utility.returnNullableStringJava() // ͜ΕOK // val str
: String? = Utility.returnNullableStringJava() // ʂʂʂ // ͜ΕOKʂʂ ʂ // val str : String = Utility.returnNullableStringJava()
JavaͰॻ͍ͨStringΛฦ͢ϝιουͷฦΓɺ StringܕʹString?ܕʹೖͰ͖Δ StringͱString?ͬͯҧ͏ܕͩͬͨͣͳͷʹʁ
ʲ࠶ܝʳ͜ΕΛ͏ͱ!(Kotlinͷίʔυ) val str = returnNullableStringKotlin() // ͜ΕOK // val str
: String? = returnNullableStringKotlin() // ͜ΕίϯύΠϧΤϥʔ Type Mismatch // val str : String = returnNullableStringKotlin() // println(str.length) // ίϯύΠϧΤϥʔ println(str?.length) // ͜ΕͳΒOK
Pla$orm(Type U"lity.returnNullableStringJava()ͷฦΓPla6orm9Type
• JavaͷࢀরܕͷϝιουͷฦΓͳͲɺPla'orm+Typeʹ • IDEͷ্ͰɺString!ͱ͔Person!ͱ͔ͬͯද͢ • ͚ͲίʔυͰɺString!ͱॻ͚ͳ͍
ܕΛ໌ࣔతʹॻ͍ͨΒͲ͏ͳΔʁ
U"lity.returnNullableStringJava()ͷฦΓ Stringܕʹೖͨ͠ΒҎޙɺStringܕͱͯ͠ѻ͏͠ String?ܕʹೖͨ͠ΒҎޙɺString?ܕͱͯ͠ѻ͏
JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ String?ʹೖ val str : String? = Utility.returnNullableStringJava() println(str?.length) //
ίϯύΠϧΤϥʔ // println(str.length)
JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ Stringʹೖ val str : String = Utility.returnNullableStringJava() println(str.length) //
ίϯύΠϧΤϥʔʮͰʯͳ͍͚Ͳ // ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δ // println(str?.length)
JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ ܕΛ໌ࣔ͠ͳ͍ͱ val str = Utility.returnNullableStringJava() // ͜ΕOK println(str?.length) //
͜ΕOKʁ(ίϯύΠϧΤϥʔʮͰʯͳ͍) println(str.length)
ͳΔ΄ͲɺΊͰͨ͠ΊͰͨ͠ʁ
ʹͳΒͳ͍ ղઆΛޙճ͠ʹ͕ͨ͠ʮ2ͭʯʂ
ʲ࠶ܝʳStringΛฦؔ͢'(Javaͷίʔυ) public class Utility { public static String returnNullableStringJava() {
return null; } }
͍ͭ͜nullฦͧ͢ʂ
JavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ ܕΛ໌ࣔ͠ͳ͍ͱ val str = Utility.returnNullableStringJava() // ͜ΕOK println(str?.length) //
ίϯύΠϧΤϥʔͰͳ͍͚ΕͲɺ // ࣮ߦ࣌ʹʮjava.lang.NullPointerExceptionʯ println(str.length)
͵ΔΆग़Δ͡ΌΜʂ Pla$orm(TypeͰɺʮNullPointerExcep5onʯͳ͛͏Δ
͏ͻͱͭ
ʲ࠶ܝʳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ Stringʹೖ val str : String = Utility.returnNullableStringJava() println(str.length) //
ίϯύΠϧΤϥʔʮͰʯͳ͍͚Ͳ // ͦΕඞཁͳ͍Αͬͯɺܯࠂ͕ग़Δ // println(str?.length)
ͩΊͦ͏ U"lity.returnNullableStringJava()nullΛฦ͢ ͜ΕΛɺStringܕʹೖͯ͠ ී௨ʹϝϯόʹΞΫηεͯ͠͠·͍ͬͯΔ
ɺͲ͏ͳΔʁ • ϝϯόʹΞΫηεͨ͠λΠϛϯάͰNullPointerExcep0on • ͦΕҎ֎ʢԿ͔ͷλΠϛϯάͰͳΜ͔ͷྫ֎Λ͛Δʣ
ਖ਼ղɺʰͦΕҎ֎ʱ ϝϯόʹΞΫηε͢Δલʹྫ֎Λ͛Δ
ʲ࠶ܝʳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ Stringʹೖ val str : String = Utility.returnNullableStringJava() println(str.length) //
ίϯύΠϧΤϥʔʮͰʯͳ͍͚Ͳ ͜ͷίʔυΛ࣮ߦ͢Δͱ...
java.lang.IllegalStateExcep0on Λ͛Δ U"lity.returnNullableStringJava()5must5not5be5null
NullPointerExcep/onͰͳͯ͘IllegalStateExcep/on ͱ͍͏͜ͱɺίϯύΠϥ͕Կ͔͍ͯ͠Δͣʂ ݟͯΈΑ͏
ʲ࠶ܝʳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ Stringʹೖ val str : String = Utility.returnNullableStringJava() println(str.length) //
ίϯύΠϧΤϥʔʮͰʯͳ͍͚Ͳ ͜ͷByte%CodeΛΈͯΈΔ IDEAͰɺTools)>)Kotlin)>)Show)Kotlin)Bytecode
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ʂ
KotlinΛBytecodeʹͯ͠ɺͦΕΛ͞ΒʹDecompile String var10000 = Utility.returnNullableStringJava(); Intrinsics.checkExpressionValueIsNotNull(var10000, "Utility.returnNullableStringJava()"); String str =
var10000; int var1 = str.length(); System.out.println(var1);
ϙΠϯτ ʮIntrinsics.checkExpressionValueIsNotNullʯ ϝϯόʹΞΫηε͢Δલʹɺ͜Ε͕ݺΕ͍ͯΔʂ
ίʔυΛݟͯΈ·͠ΐ͏ʂ Intrinsics.checkExpressionValueIsNotNull
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")); } } /*ུ*/ }
ͳΔ΄Ͳɺ͔֬ʹnullͩͬͨΒIllegalStateExcep.on͍͛ͯΔ
Ͱɺ͜Ε୭͕Αͼ͍ͩͯ͠Δͷ͔ʁ ʮcheckExpressionValueIsNotNullʯͰ୳͢
h"ps:/ /github.com/JetBrains/kotlin/blob/1.0.5/compiler/backend/src/org/jetbrains/kotlin/codegen/ AsmU?l.java#L650 AsmU%lͱ͍͏தͰݺͼग़͍ͯ͠Δʂʂʂ ͞ΒʹಡΈਐΊΔͱ
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
ͳΔ΄Ͳ
ͯ͞ɺKotlinͰίʔυΛॻ͚Δͱݴͬͯ Javaͱͷ૬ޓӡ༻ඞਢʂ nullͱͷઓ͍ͭͮ͘ͷͰ͋ͬͨ
͚ͲͳΜͱ͔͍ͨ͠
@NotNull ͱ @Nullable
@NotNull
Javaͷίʔυ // ΞϊςʔγϣϯΛ͚ͭΔ @NotNull public static String returnStringWithNotNullAnnotation() { return
""; }
@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
@NotNullͳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ Bytecode()>(JavaͰίϯύΠϧ String str = Utility.returnStringWithNotNullAnnotation(); int var1 = str.length();
System.out.println(var1);
@Nullable
Javaͷίʔυ // ΞϊςʔγϣϯΛ͚ͭΔ @Nullable public static String returnStringWithNullableAnnotation() { return
""; }
@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) // ͜ΕίϯύΠϧΤϥʔ
@NullableͳJavaͷίʔυΛKotlinͷίʔυ͔ΒݺΜͰ Bytecode()>(JavaͰίϯύΠϧ String str = Utility.returnStringWithNullableAnnotation(); Integer var1 = str
!= null?Integer.valueOf(str.length()):null; System.out.println(var1);
૬ޓӡ༻લఏͷJavaͷίʔυʹɺ @Nullabeͱ@NotNullΛ͚ͭΑ͏
Androiderͷํɺ @Nullabeͱ͍͑ʁ
LombokϢʔβʔͷํɺ @Nullableͱ͍͑ʁ
FindbugsϢʔβʔͷํɺ @Nullableͱ͍͑ʁ
JetBrainsతʹ @Nullabeͱ͍͑ʁ
@NullableΊͬͪΌ͋Δʂʂʂ ͲͷNullableͩΑʂʁ
࣮ෳରԠ͍ͯ͠Δ • 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
࣮ෳରԠ͍ͯ͠Δʢଓ͖ʣ • 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
͜͜ΒΜOK
ίʔυΛ͍·͠ΐ͏
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") )
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
·ͱΊ • Pla%orm)TypeΛཧղ͠Α͏ • Javaͱͷ૬ޓӡ༻ՕॴͰɺNullPointetExcep8on IllegalStateExcep8onՄೳੑ͋Γ • JavaͷϥΠϒϥϦʹɺ@Nullableͱ@NotNull͚ͭΑ͏
NextΞΫγϣϯ ίϯύΠϥɺJavaTypeQualifiersΛ༻͍ͯ AsmU%l͕Intrinsicsݺͼग़͢ίʔυΛు͍͍ͯΔ ͱࢥΘΕΔͷͰɺௐࠪ
͋Γ͕ͱ͏͍͟͝·ͨ͠
ؔ࿈ɾࢀߟ • 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