Gsonユーザーガイド は、Gsonで適切に動作するように、クラスのデフォルトの引数なしコンストラクターを定義する必要があると述べています。さらに、GsonのInstanceCreator
クラスの javadoc では、デフォルトコンストラクターが欠落しているクラスのインスタンスをデシリアライズしようとすると、例外がスローされると述べ、shouldそのような場合はInstanceCreator
を使用します。ただし、デフォルトのコンストラクターがないクラスでGsonの使用をテストしようとしましたが、シリアル化と逆シリアル化の両方が問題なく動作します。
以下は、逆シリアル化のコードです。引数なしのコンストラクタを持たないクラス:
public class Mushroom {
private String name;
private double diameter;
public Mushroom(String name, double diameter) {
this.name = name;
this.diameter = diameter;
}
//equals(), hashCode(), etc.
}
およびテスト:
@Test
public void deserializeMushroom() {
assertEquals(
new Mushroom("Fly agaric", 4.0),
new Gson().fromJson(
"{name:\"Fly agaric\", diameter:4.0}", Mushroom.class));
}
正常に動作します。
だから私の質問は次のとおりです:実際にデフォルトのコンストラクタを必要とせずにGsonを使用できますか、それが機能しない状況がありますか?
Gson 2.3.1以降。
Gsonのドキュメントの内容に関係なく、クラスに引数なしのコンストラクタがなく、InstanceCreater
オブジェクトを登録していない場合、Reflectionを使用してObjectConstructor
(オブジェクトを構築)を作成し、UnsafeAllocator
を作成します。クラスのインスタンスを作成するためのクラスSun.misc.Unsafe
のallocateInstance
メソッド。
この Unsafe
class は、引数のないコンストラクタの欠如を回避し、 他の多くの危険な使用法 を持っています。 allocateInstance
状態
インスタンスを割り当てますが、コンストラクターは実行しません。クラスがまだ初期化されていない場合は初期化します。
したがって、実際にはコンストラクターは必要なく、2つの引数コンストラクターを使用します。例を参照してください here 。
引数なしのコンストラクターがある場合、GsonはObjectConstructor
を使用します。これは、デフォルトのConstructor
を呼び出して使用します
yourClassType.getDeclaredConstructor(); // ie. empty, no-args
私の2セント:Gsonが言ったことに従い、引数なしのコンストラクタでクラスを作成するか、InstanceCreator
を登録します。 Unsafe
を使用すると、自分が悪い位置にいることがあります。
ここで説明されているように、 Jackson ライブラリには適切なソリューションがあります。
https://stackoverflow.com/a/11838468/285472
ポイントは、 Mix-Ins feature を介してシリアライザーに伝えることです。引数付きのコンストラクターを使用するときに使用するJSONフィールド。
そのエンティティが外部ライブラリの一部である場合、 Creator feature を使用して「リモート注釈」できます。