Modern approach:
to make NPE
compile-time error,
not run-time error
Slide 4
Slide 4 text
Nullable types in Kotlin
val s1: String = "always not null"
val s2: String? = null
s1.length ✓
✗
s2.length
"can be null or non-null"
null ✗
Slide 5
Slide 5 text
val s: String?
if (s != null) {
s.length
}
Dealing with Nullable Types
Slide 6
Slide 6 text
s?.length
val s: String?
Dealing with Nullable Types
Slide 7
Slide 7 text
val length = if (s != null) s.length else null
val s: String?
Nullability operators
val length: Int? = s?.length
Slide 8
Slide 8 text
val length = if (s != null) s.length else 0
val s: String?
Nullability operators
val length = s?.length ?: 0
Slide 9
Slide 9 text
val s: String?
if (s == null) fail()
s.length
Control-flow analysis
Slide 10
Slide 10 text
val s: String?
Making NPE explicit
s!!
throws NPE if s is null
s!!.length
Slide 11
Slide 11 text
Nullable Types Under the Hood
No performance overhead
@Nullable, @NotNull annotations
Slide 12
Slide 12 text
class Optional(val value: T) {
fun isPresent() = value != null
fun get() = value ?:
throw NoSuchElementException("No value present")
}
Nullable types ≠ Optional
Slide 13
Slide 13 text
lateinit
Slide 14
Slide 14 text
Late initialization
class KotlinActivity: Activity() {
var myData: MyData? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myData = intent.getParcelableExtra("MY_DATA")
}
}
... myData ?.foo ...
Slide 15
Slide 15 text
class KotlinActivity: Activity() {
lateinit var myData: MyData
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myData = intent.getParcelableExtra("MY_DATA")
}
}
... myData .foo ...
Late initialization
Slide 16
Slide 16 text
If the property wasn’t initialized
kotlin.UninitializedPropertyAccessException:
lateinit property myData has not been initialized
Still runtime exception, but with the detailed message
... myData .foo ...
Slide 17
Slide 17 text
Type casts
Slide 18
Slide 18 text
Type casts: as, as?
if (any is String) {
val s = any as String
s.toUpperCase()
}
not necessary
= instanceof
smart cast
if (any is String) {
any.toUpperCase()
}
Slide 19
Slide 19 text
Safe cast
val s: String? = any as? String
returns null if expression cannot be cast
val s = if (a is String) a else null