Gson反序列化一个对象数组

Ris*_*shi 2 java json gson

我有一个对象

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经能够用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);
    }               
}
Run Code Online (Sandbox Code Playgroud)

现在,我最后使用以下内容使其工作.请注意,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);
Run Code Online (Sandbox Code Playgroud)

现在这是主要问题.我想为课程做这个Point[],Point[][]等等.

我是否必须为Point的每个维度编写反序列化器,或者有更好的方法吗?

请帮忙.

Bri*_*ach 5

首先,你真的在​​你的解串器中引入了一些不需要的开销.无需创建本机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());

    }
}
Run Code Online (Sandbox Code Playgroud)

一旦你通过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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

3

您遇到的麻烦是您需要Class动态获取并且需要数组类型.您可以通过[L在完全限定的类名前面添加数组类型来实现此目的:

Class myClass = Class.forName("[L" + "my.package.Point");
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

输出:

3
3