微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Gson反序列化问题-如果Type参数是子类,则无法反序列化

如何解决Gson反序列化问题-如果Type参数是子类,则无法反序列化

在变量Generic<Parent> generic Master 类中,我正在main()中传递子对象。在序列化期间,我得到正确的输出。但是在反序列化Child Object时缺少。任何人都可以提出建议。

public class GenericSample {
    public static void main(String[] args) {
        Generic<Parent> generic = new Generic<Parent>();
        Child child = new Child();
        child.setName("I am child");
        generic.setT(child);

        Gson gson = new Gson();

        Master master = new Master();
        master.setId(2);
        master.setGeneric(generic);

        String valMaster = gson.toJson(master);
        System.out.println(valMaster);
        /*
         * Output: {"id":2,"generic":{"t":{"name":"I am child"}}}
         */

        Master master2 = gson.fromJson(valMaster,Master.class);
        String valMaster2 = gson.toJson(master2);
        System.out.println(valMaster2);
        /*
         * Child Object is missing
         * Output: {"id":2,"generic":{"t":{}}}
         */
    }

    static class Master {
        private int id;
        private Generic<Parent> generic;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public Generic<Parent> getGeneric() {
            return generic;
        }

        public void setGeneric(Generic<Parent> generic) {
            this.generic = generic;
        }

    }

    static class Generic<T> {
        T t;

        public T getT() {
            return t;
        }

        public void setT(T t) {
            this.t = t;
        }
        
    }
    static class Parent {
        private String type;

        public String getType() {
            return type;
        }

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

    }

    static class Child extends Parent {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

}

解决方法

问题

Gson尝试将通用值反序列化为Parent,而不是Child。由于typenull,因此在反序列化的对象中看不到显示为{}的数据。如果添加child.setType("type");,则输出将变为:

  • valMaster1{"id":2,"generic":{"t":{"name":"I am child","type":"type"}}}
  • valMaster2{"id":2,"generic":{"t":{"type":"type"}}}

但是,name类中不存在字段Parent,但Child类中却没有{em> Gem,而Gson根本不知道{{1 }}是(如果是)并且完全忽略该值,这是正确的行为。

解决方案

我发现基本上有两个选择(为简洁起见,我使用all-args构造函数):

  1. 将上限通用类型参数提升为Parent类,并在反序列化时使用MasterChild指定特定的com.google.gson.reflect.TypeToken类型:

    java.lang.reflect.Type
    static class Master<T extends Parent> {
        private int id;
        private Generic<T> generic;
    
        /* getters,setters and all-args constructor */
    }
    
  2. Child child = new Child("I am child"); Generic<Parent> generic = new Generic<>(child); Master<Parent> master = new Master<>(2,generic); Gson gson = new Gson(); String valMaster = gson.toJson(master); System.out.println(valMaster); // {"id":2,"generic":{"t":{"name":"I am child"}}} Type type = new TypeToken<Master<Child>>() {}.getType(); Master<Child> master2 = gson.fromJson(valMaster,type); String valMaster2 = gson.toJson(master2); System.out.println(valMaster2); // {"id":2,"generic":{"t":{"name":"I am child"}}} 类内对特定的通用类型Generic<Child>进行硬编码。反序列化使方法变得更容易,但是设计的灵活性较差:

    Master
    static class Master {
        private int id;
        private Generic<Child> generic;
    
        /* getters,setters and all-args constructor */
    }
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?