Lie to me Kotlin!

Peter Nagy
3 min readNov 24, 2020

I am working as an Android developer. Earlier most crashes was caused by NullPointerException (NPE). Why ? Because there was an object and one or many fields were not initialised in the object or any method wanted to use a field before we initialised it. Ok, how can we avoid from NPE ? For example we can wrote Unit Tests. Yes, however it is really hard to test all cases, especial when something is on the View side or it is really close to the OS.

Later there are some annotations -> @Nullable and @NonNull
It was useful to use it however only the IDE shows a warning when developer did not handle the situation. It was better then nothing but it is not too safe solution.

Kotlin

Kotlin is a great language. There are lot of great language feature for example "?" operator. Based on this features we can reduce the NPEs. (Much less crashes and NPE based crash caught till I have used Kotlin)

But way a minute

When you want to create a network call (in an Android app) you can use a very popular library Retrofit. It will do all task -> serialise objects, create JSON, network call, deserialise objects.

There is an data object:

data class MovieHero(val name: String, val movie: Movie, val good: Boolean)data class Movie(val title: String)

And there is a JSON from network:

{"name": "Luke Skywalker", "good": true }

What will happen ? Nothing bad. There will be an object without any problem. And when you will use it, like access movie field's title you will get a KotlinNullPointerException. :(

So it seems Kotlin lie to me. We have an object with non nullable field and it is null. How is possible it ?

Sorry, I did not mention an important thing. When you use Retrofit you can setup serialiser like GSON. (It could be Jackson, Moshi, etc…) Earlier I prefer GSON but there is a big problem. GSON is a Java library and Kotlin-Java interoperability is absolute good there could be problems.
You can find the reason on the StackOverflow ->

It means GSON will create an object not safe way. :( OMG

Ok, what can we do ? Change the serialiser. There is a Kotlin library which support serialising objects.

It is a great library with help of it we can use default value too. And Retrofit support to use it. There is a converter factory if you want to use both in your project.

Any way what can we do if we can not replace GSON ?
It is possible if you are using a legacy app with some legacy conditions.
The solution will be not too simple. We need duplicate all objects.

1. Network objects will be unsafe objects. They will contain all non nullable fields.

data class UnsafeMovieHero(val name: String?, val movie: Movie?, val good: Boolean?)data class UnsafeMovie(val title: String?)

2. There are safe objects what we can use it later.

data class SafeMovieHero(val name: String, val movie: Movie, val good: Boolean)data class SafeMovie(val title: String)

3. We need create conversion between objects above.

fun conversion.UnsafeMovieHero(): SafeHero {
return SaveHero(name = this.name!!, movie = this.movie!!.conversion, good = this.good!!)
}
fun conversion.UnsafeMovie(): SafeMovie {
return SaveMovie(title = this.title!!
}

4. When we are using RX, then we can insert conversion into RX chain.

With 4. we can ensure when conversion was failed then network related RX chain will be failed. It means error message will be same like when network call failed. :)

We can solve the problem however it is really not good, because we will generate the boilerplate code (not productive code).
It is better to let use a library and write productive code than write not productive code (waste of time and resources, etc).

--

--