Kotlin for Android Developers


Download 1.04 Mb.
Pdf ko'rish
bet57/79
Sana18.06.2023
Hajmi1.04 Mb.
#1588404
1   ...   53   54   55   56   57   58   59   60   ...   79
Bog'liq
Kotlin for Android Developers Learn Kotlin the Easy Way While Developing an Android App ( PDFDrive )

20 Null safety in Kotlin
Null safety is one of the most interesting features about Kotlin if you are currently working with
Java 7. But as you have seen during this book, it’s so implicit in the language we hardly had to worry
about it until the previous chapter.
Being
null
considered the
billion-dollar mistake by its own creator²³
, it’s true that we sometimes
need to define whether a variable contains a value or not. In Java, though annotations and IDEs are
helping a lot these days, we can still do something like:
1
Forecast forecast = null;
2
forecast.toString();
This code will perfectly compile (you may get a warning from the IDE), and when it runs, it will
obviously throw a
NullPointerException
. This is really unsafe, and as we can think we should be
able to have everything under control, as the code grows we’ll start losing track of the things that
could be null. So we end up with lots of
NullPointerException
s or lots of nullity checks (probably
a mix of both).
20.1 How Null types work
Most modern languages solve this issue in some way, and the Kotlin way is quite peculiar and
different from the rest of similar languages. But the golden rule is the same: if a variable can be null,
the compiler will force us deal with it in some way.
The way to specify that a variable can be null is by adding a question mark to the end of its type.
As everything is an object in Kotlin (even Java primitive types), everything can be null. So, of course,
we can have a nullable integer:
1
val a: Int? = null
You can’t work directly with a nullable type without doing some checks before. This code won’t
compile:
²³
https://en.wikipedia.org/wiki/Tony_Hoare
89


20 Null safety in Kotlin
90
1
val a: Int? = null
2
a.toString()
The previous code could be null, and the compiler is aware of that, so until the nullity is checked,
you won’t be able to use it. Here it is when another feature of the Kotlin compiler comes into action:
the smart cast. If we check the nullity of an object, from that moment the object is automatically
casted to its non-nullabe type. Let’s see an example:
1
val a: Int? = null
2
...
3
if (a != null) {
4
a.toString()
5
}
Inside the
if
,
a
becomes
Int
instead of
Int?
, so we can use it without checking nullity anymore.
The code outside the
if
context, of course, will have to deal with it. This only works if a variable
can’t be concurrently modified, because otherwise the value could’ve been changed from another
thread and the previous check would be false at that moment. It is supported on
val
properties or
local (
val
or
var
) variables
This can sound like a lot of work. Do we have to fill all our code with nullity checks? Of course
not. First, because most of the time you won’t need null objects. Null references are more unused
that one could think, you’ll realise when you start figuring out whether a variable should be null or
not. But Kotlin also has its own mechanisms to do this task easier. We can, for instance, simplify the
previous code to:
1
val a: Int? = null
2
...
3
a?.toString()
Here we are using the safe call operator (?.). Previous line will only be executed if the variable is
not null. Otherwise, it will do nothing. And we can even provide an alternative for the null case
using the Elvis operator (?:):
1
val a: Int? = null
2
...
3
val myString = a?.toString() ?: ""
Since
throw
and
return
are also expressions in Kotlin, they can be used in the right side of the Elvis
operator:


20 Null safety in Kotlin
91
1
val myString = a?.toString() ?: return false
1
val myString = a?.toString() ?: throw IllegalStateException()
However, there can be situations when we know for sure we are dealing with a non-nullable variable,
but the type is nullable. We can force the compiler to deal with nullable types skipping the restriction
by using the !! operator:
1
val a: Int? = null
2
a!!.toString()
The previous code will compile, but will obviously crash. So we must make sure we only use it in
very specific situations. Usually we can choose alternative solutions. A code full of !! will be a smell
of something not being dealt properly.

Download 1.04 Mb.

Do'stlaringiz bilan baham:
1   ...   53   54   55   56   57   58   59   60   ...   79




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling