2017-05-22 23 views
1

イム:KotlinデータクラスGsonシリアル化問題

情報を更新チェックするために使用されるデータのクラス:また

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 
} 

使用のutilオブジェクトフォーム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(); 
    } 
} 

私はそれをテストする場合:

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

私が取得:

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

何? info.isForceUpdate = false ???
その後、私はlateinitまたはby lazy{}を試しましたが、まだ動作しません。 どうすればいいですか。私はinfo.force==1を直接使っていますが、なぜこれが起こったのかを知りたいのです。

+0

これが役立つかどうか確認してください:http://stackoverflow.com/questions/39962284/gson-deserialization-with-kotlin-initializer-block-not-called – hotkey

+0

シリアライズライブラリでコンストラクタを正しく呼び出すには( 'Unsafe'を使用してインスタンス化するのではなく)[Moshi](https://medium.com/square-corner-blog/kotlins-a-great-language-for-json-fcd6ef99256b)に興味があるかもしれません。それはいくつかの点でGsonの後継者と見ることができます。 –

答えて

2

問題は、プロパティval isForceUpdate = force == 1がクラスのインスタンス生成時に1回計算され、フィールドに格納されることです。 GsonはUnsafeを使用してクラスをインスタンス化するため、このフィールドはデフォルト値falseに設定されます。

あなたがこの問題を解決するためにしなければならないすべては計算されたプロパティにプロパティを変更します:値は任意のコールで計算され、フィールドに格納されないように

val isForceUpdate get() = force == 1 

+0

ありがとう、それは動作します。 – XieEDeHeiShou

関連する問題