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);

现在这是主要问题。我想为 classes 做这个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

当您开始谈论多个维度时,这有点难看。它可以工作......您可以使用附加[来表示尺寸......但是您仍然需要将其作为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

GSon 有自己的ArrayTypeAdapter内部使用。我想当您尝试反序列化数组时会自动使用它,因为对于List其他集合也是如此。

由于它是 GSon 内部的,因此您通常不必执行任何操作来启用或使用它。

于 2013-07-12T11:06:01.257 回答