Since we are talking about Gson here, I have a dif...
# android
h
Since we are talking about Gson here, I have a different question. My data class has member properties that has default values, e.g.
Copy code
data class Person(val name: String, val age: Int, val desc: String = "")
When cloud JSON (via Retrofit and Gson) comes back w/ null value for
desc
field, the resultant
Person
instance will have null value for
desc
field, instead of empty string. So the non-null field
desc
can have null value. I searched online for some solutions but they all seem hacky, anyone has any good suggestion?
👍 1
m
Gson is (currently) Java only so it has no knowledge about Kotlin default values and uses Java’s reflection to set the values. Kotlin on the other hand won’t do any checking on the actual value of desc until you call desc, assuming it will be non-nullable, and get a NPE. There are workarounds with custom getters in Gson, but I would recommend using a library written in Kotlin, so Moshi would be a good choice.
h
Thank you Max! Will give it a try
g
Moshi is not written in Kotlin
Moshi just has additional library adapter for Kotlin
You can use Gson with default arguments, but you must have default constructor, to do that you can add default arguments to all constructor params
uses Java’s reflection to set the values
Moshi and Jackson, everyone use Java reflections by default. moshi-kotlin also uses reflections, but Kotlin reflections, but also provides an option to generate adapters using kapt
h
Thanks Andrey! Will give that a try first. It's just the class I have has a lot member properties lol
g
In you case if you do this:
data class Person(val name: String = "", val age: Int = -1, val desc: String = "")
Kotlin will generate default constuctor and Gson will use this constructor instead of sun.misc.Unsafe to create an instance of the object and then set values from Json using reflection
But be careful with nullable values, if Json has
"desc": null
, Gson will overwrite your default empty string with null and your program will crash on access to this property
h
Yes, that's exactly the problem I'm trying to solve here.
desc
can have null value, which will lead to runtime NPE.
g
So you cannot use default string in this case
if you Json doesn’t contain desc field, everything will be fine
h
🙂 yes, this is the corner case I'm trying to resolve
g
so the only safe option in this casse:
val desc: String? = ""
h
okay got it! thanks!
m
Moshi just has additional library adapter for Kotlin
Yeah sorry thats what I meant even though its not what I wrote… I didn’t actually know that the default values work when every property has a default, but the part about passing in null is pretty risk in my opinion, unless you are in full control of the API you call and can make sure nulls are never included in a JSON.
g
make sure nulls are never included in a JSON
Yes, if you not sure about API you always can use nullable values, Kotlin provides a lot of tools for that
But again, I agree, Gson and other libraries without direct Kotlin support are not so safe and pleasant to use, but still useful. For example Moshi has support of Kotlin, but I don’t want to include huge kotlin-reflect because of this or even generate 1 additional adapter class for each of my data classes. It’s just a trade-off So for now pure Moshi or Gson is fine for my (and I suppose not only my) case, but I would like to use kotlinx.serialization at some point, sounds like a best approach in global perspective
g
This is a set of DSLs to make Geon usage more idiomatic, but as I understand it changes nothing about nullability or default arguments