Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gson:从包装类反序列化抽象子类列表_Java_Json_Serialization_Gson_Deserialization - Fatal编程技术网

Java Gson:从包装类反序列化抽象子类列表

Java Gson:从包装类反序列化抽象子类列表,java,json,serialization,gson,deserialization,Java,Json,Serialization,Gson,Deserialization,我对Gson和JSON都很陌生。 我的问题是,当创建泛型类列表并将其存储在包装器obj中时,我无法反序列化回子obj 这是主要代码 public static void main(String[] arg) { block b = new block(); List<Shape> shapes = new ArrayList<Shape>(); Circle c = new Circle(); c.setRadius(1); c

我对Gson和JSON都很陌生。 我的问题是,当创建泛型类列表并将其存储在包装器obj中时,我无法反序列化回子obj

这是主要代码

public static void main(String[] arg) {
    block b = new block();

    List<Shape> shapes = new ArrayList<Shape>();

    Circle c = new Circle();
    c.setRadius(1);
    c.setType("cir");
    Square s = new Square();
    s.setSide(4);
    s.setType("sq");

    shapes.add(c);
    shapes.add(s);

    b.setShape(shapes);

    String json = new Gson().toJson(b);
    System.out.println(json);

    Object obj = new Gson().fromJson(json, block.class);
    block bobj = (block) obj;

    List<Shape> li = bobj.getShape();
    Shape sh = (Shape)li.get(0);

    System.out.println(sh.getClass().getCanonicalName());
    System.out.println(sh.toString());
}
publicstaticvoidmain(字符串[]arg){
块b=新块();
列表形状=新建ArrayList();
圆c=新的圆();
c、 设定半径(1);
c、 setType(“cir”);
正方形s=新正方形();
s、 侧边(4);
s、 setType(“sq”);
加上(c);
形状。添加(s);
b、 设置形状(形状);
字符串json=new Gson().toJson(b);
System.out.println(json);
Object obj=new Gson().fromJson(json,block.class);
块体bobj=(块体)obj;
List li=bobj.getShape();
Shape sh=(Shape)li.get(0);
System.out.println(sh.getClass().getCanonicalName());
System.out.println(sh.toString());
}
我把它作为输出 {"shape":[{"radius":1,"type":"cir"},{"side":4,"type":"sq"}]} com.ups.pcs.test.TestTypeAdaptor.Shape com.ups.pcs.test.TestTypeAdaptor$Shape@3c6f579 {“形状”:[{“半径”:1,“类型”:“cir”},{“侧面”:4,“类型”:“sq”}]} com.ups.pcs.test.testTypeAdapter.Shape com.ups.pcs.test.testTypeAdapter$Shape@3c6f579

以下是我剩余的代码:

static class block implements Serializable {
      List<Shape> shape = null;

    public block() {

    }

    public List<Shape> getShape() {
        return shape;
    }

    public void setShape(List<Shape> shape) {
        this.shape = shape;
    }

  }

  static class Shape implements Serializable{
    String type;

    public Shape(){}
    public void setType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

  }

  private static final class Circle extends Shape implements Serializable{
    int radius;

    public Circle(){}
    public int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    public String toString() {
        return "t: " + type + "r: " + radius;
    }
  }

  private static final class Square extends Shape implements Serializable{
    int side;

    public Square(){}
    public int getSide() {
        return side;
    }

    public void setSide(int side) {
        this.side = side;
    }

    public String toString() {
        return "t: " + type + "s: " + side;
    }
  }
静态类块实现可序列化{
列表形状=空;
公众大厦(){
}
公共列表getShape(){
返回形状;
}
公共无效集合形状(列表形状){
这个形状=形状;
}
}
静态类形状实现可序列化{
字符串类型;
公共形状(){}
公共void集合类型(字符串类型){
this.type=type;
}
公共字符串getType(){
返回类型;
}
}
私有静态最终类圆形扩展形状实现可序列化{
整数半径;
公共圈(){}
公共int getRadius(){
返回半径;
}
公共空间设置半径(整数半径){
这个半径=半径;
}
公共字符串toString(){
返回“t:+类型+”r:+半径;
}
}
私有静态最终类Square扩展形状实现可序列化{
内侧;
公共广场(){}
公共int getSide(){
返回侧;
}
公共无效设置侧(内部侧){
这个边=边;
}
公共字符串toString(){
返回“t:+类型+”s:+侧;
}
}

我看到一些帖子谈论使用定制的TypeAdapter或TypeAdapter工厂,我不知道如何使用。顺便说一句,我使用的是Gson2.2.2版本

这是迄今为止我找到的最好答案。。。 如果有人找到比这更好的解决方案,请告诉我。 我还没有测试过它的运行速度

基本上,为主对象创建自定义反序列化器,并在查看每个对象时确定属性类

  public static class BlockDeserializer implements JsonDeserializer<Block> {

    @Override
    public Block deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json == null)
            return null;
        else {
            Block block = new Block();
            JsonObject jo = json.getAsJsonObject();
            JsonArray ja = jo.getAsJsonArray("shape");

            List<Shape> shapes = new ArrayList<Shape>();

            for(JsonElement je : ja) {
                JsonObject jeo = je.getAsJsonObject();

                if(jeo.get("radius") != null) {             
                    shapes.add(new Gson().fromJson( jeo , Circle.class));                       
                } else {
                    shapes.add(new Gson().fromJson( jeo , Square.class));           
                }
            }

            block.shape = shapes;

            return block;
        }
    }
}   
公共静态类BlockDeserializer实现JsonDeserializer{
@凌驾
公共块反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
if(json==null)
返回null;
否则{
块=新块();
JsonObject jo=json.getAsJsonObject();
JsonArray ja=jo.getAsJsonArray(“形状”);
列表形状=新建ArrayList();
对于(JsonElement je:ja){
JsonObject jeo=je.getAsJsonObject();
如果(jeo.get(“半径”)!=null){
add(new Gson().fromJson(jeo,Circle.class));
}否则{
add(new Gson().fromJson(jeo,Square.class));
}
}
block.shape=形状;
返回块;
}
}
}   

也将形状修改为抽象形状,但无法成功运行<代码>线程“main”java.lang.RuntimeException中的异常:调用public com.ups.pcs.test.TestTypeAdapter$Shape()失败,无参数