Why is this an issue?
When accessing Map
elements by key, you should keep in mind that value might not be present. If value is not present,
null
will be returned. To make it possible, the type of returned value is nullable. In Kotlin, it’s not usually convenient to operate
with nullable types, so developers usually try to avoid them or convert them to non-nullable types. One of the possible solutions is to use
!!
(non-null assertion operator). If during the runtime the actual value applied to non-null asserrion operator was null
,
then NullPointerException
will be thrown. While in some cases it could still be legitimate to use !!
, accesing
Map
values is not one of them. Usage of a !!
when accesing Map
values is a bad practice and can lead to
NullPointerException
in Kotlin and potential crashes, if Java interop was involved.
How to fix it
You should avoid using the non-null assertion operator when accessing Map
elements.
Instead, you can:
- return an instance of a nullable type.
- use
getValue
. This will throw NoSuchElementException
when an element is not present.
- use either
getOrElse
or getOrDefault
functions and explicitly specify the behavior in case of a null value.
- use an elvis operator
?:
to specify the behavior in case of a null value.
Code examples
Noncompliant code example
This example will throw a NullPointerException
at the !!
operator because map
doesn’t have a key
123
and the result of get(123)
will be null.
val l = mapOf(1 to "one", 2 to "two", 3 to "five")
l.get(123)!! // Noncompliant
l[123]!! // Noncompliant
Compliant solution
By removing the non-null assertion operator the result of the get(123)
call will return an instance of a nullable type, and the user
can handle the potential null
value properly.
val l = mapOf(1 to "one", 2 to "two", 3 to "five")
l.get(123) // Compliant, returns nullable
l[123] // Compliant, returns nullable
l.getValue(123) // Compliant, throws NoSuchElementException
l.getOrElse(123 ) { "empty" } // Compliant, has default
l.getOrDefault(123, "empty") // Compliant, has default
l[123] ?: "empty" // Compliant, has default
Resources
Documentation
Articles & blog posts