2

私はオブジェクトを持っています

public class Point{
    int x, y;

    Point(int x, int y){
        this.x = x;
        this.y = y;
    }

    public String toString(){
        String ret = "[";
        ret += Integer.toString(x);
        ret += ", ";
        ret += Integer.toString(y);
        ret += "]";
        return ret;
    }
}

次のように、Gson を使用してこのオブジェクトを逆シリアル化することができました。

class PointDeserializer implements JsonDeserializer<Point>{
    @Override
    public Point deserialize(JsonElement json, Type typeOfT,
    JsonDeserializationContext context) throws JsonParseException {
        Gson gson = new Gson();
        int[] tmp = gson.fromJson(json, int[].class);
        int a = tmp[0];
        int b = tmp[1];
        return new Point(a,b);
    }               
}

今、私はついにそれを機能させるために以下を使用します。type と str は文字列であることに注意してください。

Class myClass = Class.forName(type);
Class myClassDeserializer = Class.forName(type + "Deserializer");
Gson gson = new GsonBuilder().registerTypeAdapter(myClass, myClassDeserializer.newInstance()).create();
Object ret = gson.fromJson(str, myClass);

ここが主な問題です。Point[]私はクラスなどに対してもこれをやりたいですPoint[][]

Point のすべての次元に対してデシリアライザーを作成する必要がありますか、それともより良い方法がありますか?

助けてください。

4

3 に答える 3

6

まず、デシリアライザーに不要なオーバーヘッドを少し導入しています。ネイティブ Java 配列を作成する必要はありません。すでに JSON 配列があります。

class PointDeserializer implements JsonDeserializer<Point> {

    @Override
    public Point deserialize(JsonElement json, Type typeOfT,
        JsonDeserializationContext context) throws JsonParseException {

        JsonArray array = json.getAsJsonArray(); 
        return new Point(array.get(0).getAsInt(), array.get(1).getAsInt());

    }
}

を介してGsonに登録するとregisterTypeAdapter、そのタイプの配列は「そのまま機能します」:

public static void main(String[] args)
{
    String json = "[ [1,2], [3,4] ]";

    Gson gson = new GsonBuilder().registerTypeAdapter(Point.class, 
                    new MyPointDeserializer()).create();

    Point[] mpa = gson.fromJson(json, Point[].class);        
    System.out.println(mpa[1].x);
}

出力:

3

Class遭遇する問題は、動的に取得する必要があり、配列型が必要なことです。[L完全修飾クラス名の前に追加することで、配列型に対してこれを実現できます。

Class myClass = Class.forName("[L" + "my.package.Point");

myClass今保持していますPoint[].class

複数の次元について話し始めると、これは急いでかなり醜くなります。それは機能します...追加を使用して次元を表すことができます...しかし、それでもandキャストなど[として戻す必要があります.Object

正直なところ、それを行うより良い方法は、 を持つList型を使用することTypeTokenです。

public static void main(String[] args) 
{

    String json = "[ [[1,2]], [[3,4]] ]";

    Gson gson = new GsonBuilder().registerTypeAdapter(Point.class, new MyPointDeserializer()).create();

    Point[][] mpa = gson.fromJson(json, Point[][].class);

    System.out.println(mpa[1][0].x);

    Type listType = new TypeToken<ArrayList<ArrayList<Point>>>(){}.getType();

    List<List<Point>> list = gson.fromJson(json, listType);

    System.out.println(list.get(1).get(0).x);

}

出力:

3
3

于 2013-07-13T19:50:21.300 に答える
2

これは、オブジェクトの配列を逆シリアル化する方法です。

Gson gson = new Gson();
Type collectionType = new TypeToken<List<YourObject>>(){}.getType();
List<YourObject> yourObjectsList= gson.fromJson(jsonString, collectionType);

ハッピーコーディング:)

于 2015-10-20T06:42:05.527 に答える
0

ArrayTypeAdapterGSon には、内部で使用される独自のものがあります。Listおよび他のコレクションに対しても同じことが行われるため、配列を逆シリアル化しようとすると、自動的に使用されると思います。

GSon の内部であるため、通常は有効化または使用するためのアクションを実行する必要はありません。

于 2013-07-12T11:06:01.257 に答える