3

Im a little bit confused for my kotlin class didn't work as expected:

the data class used to check update info:

data class UpdateInfo constructor(//kotlin class
    val description: String,
    val force: Int,
    val platform: String,
    val title: String,
    val url: String,
    @SerializedName("version")
    val versionCode: Int = 0
) : Serializable {
    val isForceUpdate = force == 1
}

also a util used to decode object form json:

public class JsonUtil {//java class
    private static final Gson gson;
    static {
        BooleanAdapter booleanAdapter = new BooleanAdapter();
        gson = new GsonBuilder()
            .serializeNulls()
            .disableHtmlEscaping()
            .setLenient()
            .registerTypeAdapter(Boolean.class, booleanAdapter)
            .registerTypeAdapter(boolean.class, booleanAdapter)
            .create();
    }
}

when I test it:

val json = "{\"force\"=\"1\"}"
val info = JsonUtil.fromJsonObject(json, UpdateInfo::class.java)
println(info)
println(info.force == 1)
println(info.isForceUpdate)

I get:

UpdateInfo(description=null, force=1, platform=null, title=null, url=null,versionCode=0)
true
false

What?? info.isForceUpdate = false ???
Then I tried lateinit or by lazy{}, still not works. So, what should I do..I'm useing info.force==1 directly now,but I still want to know why this happend.

Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
DevDengChao
  • 198
  • 15
  • Please check if this helps: http://stackoverflow.com/questions/39962284/gson-deserialization-with-kotlin-initializer-block-not-called – hotkey May 22 '17 at 07:27
  • If you want your constructor to be called properly by the serialization library (instead of using `Unsafe` to instantiate it), you may be interested in [Moshi](https://medium.com/square-corner-blog/kotlins-a-great-language-for-json-fcd6ef99256b), which in some ways can be seen as a successor to Gson. – Christian Brüggemann May 22 '17 at 08:33

1 Answers1

3

The problem is that the property val isForceUpdate = force == 1 is computed once at the instantiation of the class and then stored in a field. Because Gson is using Unsafe to instantiate the class, the field is set to its default value false.

All you have to do to fix this is change the property to a computed property:

val isForceUpdate get() = force == 1

so that the value is computed on any call and not stored in a field.

Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148