In json -> class, Gson will only use the no-argument constructor. If it doesn’t, Gson will create it himself through Unsafe and won’t use any other constructor.

Air safety design

To be clear, Gson is not in charge of Kotlin’s air-safety design. As long as Json data is specified as null, even if you write non-null data will be empty when instantiated. Such as:

Kotlin

data class User(
        val age: Int = 11.val name: String = "lucy".val phone: String = "13888888888"
)
Copy the code

Json

"name" : null
Copy the code

User. phone = 13888888888 user.age = 11

usedata classIn the case

You must make sure that all variables are given default values so that the data class has no parameter constructor, so that the default values you define are valid. If not all values are given, the data type is 0, the Boolean is false, and the other types are null. Such as:

Kotlin

data class User(
        val age: Int.val name: String = "lucy".val phone: String = "13888888888"
)
Copy the code

Json

"name" : null
Copy the code

Since age does not have a default value, Kotlin will not give the class its default no-argument constructor when compiled. Gson, using Unsafe, will not use Kotlin’s constructor to assign values. Age = 0, name = null, phone = null

The solution

1.Moshi

Moshi does support Kotlin’s null security, but there are some problems. First of all, the Json data returned by the server may not be null. If you set the code to be non-null, Moshi will throw the exception directly and do not parse it. The feeling is a little inconsistent with the actual development and use, maybe other data will be useful ah, not just because of an abnormal data cause all the use of my own code, I feel at ease with these judgments should be in my own code. And switching libraries has a cost!!

2. Write it safely
data class User(
        val age: Int.@SerializedName("name") private val _name: String?
) {
    val name
        get() = _name ? :"lucy"
}
Copy the code

You don’t want it to be null, so even if the server sends a null value by mistake, you have to use a default value instead, so you can write it like this. Obviously, this solution is very verbose, and if you have a lot of variables, you’re going to have to write a lot of code, so I’m going to use data class just for convenience, but you can go to the trouble of doing that.

Use advice

So the initial advice I use is, leave everything empty!! !

  • When you define a class, you must assign default values to all variables and nullable values to all non-data types.
  • determineJsonIt’s not going to be in there, but it’s going to be in some tool properties that define default values.

Like this:

data class User(
        val age: Int = 0.val name: String? = null.val pay: Boolean = false.val phone: String = "13888888888"
)
Copy the code