当前位置: 首页 > 面试题库 >

Java gson的多态性

麻和雅
2023-03-14
问题内容

我在使用Gson反序列化json字符串时遇到问题。我收到一系列命令。该命令可以是start,stop或其他类型的命令。我自然具有多态性,并且start / stop命令从command继承。

如何使用gson将其序列化回正确的命令对象?

似乎我只获得基本类型,即声明的类型,而从未获得运行时类型。


问题答案:

根据我的研究以及使用gson-2.0时,你确实不想使用registerTypeHierarchyAdapter方法,而是更平凡的registerTypeAdapter。而且,你当然不需要为派生类做instanceofs或编写适配器:只为基类或接口提供一个适配器,当然,你对派生类的默认序列化感到满意。无论如何,这是代码(删除了打包和导入)(也可以在github中找到):

基类(在我的情况下为接口):

public interface IAnimal { public String sound(); }

这两个派生类Cat:

public class Cat implements IAnimal {

    public String name;

    public Cat(String name) {
        super();
        this.name = name;
    }

    @Override
    public String sound() {
        return name + " : \"meaow\"";
    };
}

And Dog:

public class Dog implements IAnimal {

    public String name;
    public int ferocity;

    public Dog(String name, int ferocity) {
        super();
        this.name = name;
        this.ferocity = ferocity;
    }

    @Override
    public String sound() {
        return name + " : \"bark\" (ferocity level:" + ferocity + ")";
    }
}

IAnimalAdapter:

public class IAnimalAdapter implements JsonSerializer<IAnimal>, JsonDeserializer<IAnimal>{

    private static final String CLASSNAME = "CLASSNAME";
    private static final String INSTANCE  = "INSTANCE";

    @Override
    public JsonElement serialize(IAnimal src, Type typeOfSrc,
            JsonSerializationContext context) {

        JsonObject retValue = new JsonObject();
        String className = src.getClass().getName();
        retValue.addProperty(CLASSNAME, className);
        JsonElement elem = context.serialize(src); 
        retValue.add(INSTANCE, elem);
        return retValue;
    }

    @Override
    public IAnimal deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException  {
        JsonObject jsonObject = json.getAsJsonObject();
        JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
        String className = prim.getAsString();

        Class<?> klass = null;
        try {
            klass = Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new JsonParseException(e.getMessage());
        }
        return context.deserialize(jsonObject.get(INSTANCE), klass);
    }
}

和测试类:

public class Test {

    public static void main(String[] args) {
        IAnimal animals[] = new IAnimal[]{new Cat("Kitty"), new Dog("Brutus", 5)};
        Gson gsonExt = null;
        {
            GsonBuilder builder = new GsonBuilder();
            builder.registerTypeAdapter(IAnimal.class, new IAnimalAdapter());
            gsonExt = builder.create();
        }
        for (IAnimal animal : animals) {
            String animalJson = gsonExt.toJson(animal, IAnimal.class);
            System.out.println("serialized with the custom serializer:" + animalJson);
            IAnimal animal2 = gsonExt.fromJson(animalJson, IAnimal.class);
            System.out.println(animal2.sound());
        }
    }
}

当运行Test :: main时,将得到以下输出:

serialized with the custom serializer:
{"CLASSNAME":"com.synelixis.caches.viz.json.playground.plainAdapter.Cat","INSTANCE":{"name":"Kitty"}}
Kitty : "meaow"
serialized with the custom serializer:
{"CLASSNAME":"com.synelixis.caches.viz.json.playground.plainAdapter.Dog","INSTANCE":{"name":"Brutus","ferocity":5}}
Brutus : "bark" (ferocity level:5)

我实际上也使用registerTypeHierarchyAdapter方法完成了上述操作,但这似乎需要实现自定义的DogAdapter和CatAdapter序列化器/反序列化器类,这在你想向Dog或Cat添加另一个字段时很难维护。



 类似资料:
  • 有人能提供一个简单的例子来解释Java中动态多态性和静态多态性之间的区别吗?

  • 多态的概念其实不难理解,它是指对不同类型的变量进行相同的操作,它会根据对象(或类)类型的不同而表现出不同的行为。 事实上,我们经常用到多态的性质,比如: >>> 1 + 2 3 >>> 'a' + 'b' 'ab' 可以看到,我们对两个整数进行 + 操作,会返回它们的和,对两个字符进行相同的 + 操作,会返回拼接后的字符串。 也就是说,不同类型的对象对同一消息会作出不同的响应。 看下面的实例,来

  • 问题内容: 当我开始寻找多态性的好处时,在这里发现了这个问题。但是在这里我找不到答案。让我告诉我想找到什么。这里有一些课程: 现在,我在Demo类中创建了两个对象,它们是的引用。我完全了解,我可以从对象中调用方法,但是该方法对于对象是隐藏的。现在我的问题是为什么我应该使用多态性或为什么我应该使用 当我同意的时候 多态物体的效率好还是重量轻?这两个对象的基本目的和区别是什么?有什么区别和? 问题答案

  • 本文向大家介绍Java中的多态性,包括了Java中的多态性的使用技巧和注意事项,需要的朋友参考一下 多态是对象采取多种形式的能力。当使用父类引用来引用子类对象时,会在OOP中最常见地使用多态。 任何可以通过多个IS-A测试的Java对象都被视为多态的。在Java中,所有Java对象都是多态的,因为任何对象都将通过IS-A测试以了解其自身类型和Object类。 重要的是要知道访问对象的唯一可能方法是

  • 在尝试了几个变体之后,我一直在尝试让我的Spring HATEOAS控制器执行多态性。 我的第一个变体是将资源实现为资源的实例,我的对象是内容。基类定义如下: 获取单个实例或页面时,会引发以下异常: 此处提供完整的复制:https://github.com/Bert-R/spring-hateoas-polymorphism/tree/master/src/main/java/nu/famroos

  • 我在比较C++多态性的以下方法的性能: 方法[1]。使用boost变体的静态多态性,每个方法都有一个单独的访问者method[2]。静态多态性使用boost变体,单个访问者调用不同的方法,使用方法重载方法[3]。平原老动态多态性 一些发现: 方法[1]似乎明显优于方法[2]和[3] 方法[3]在大多数情况下都优于方法[2] 我的问题是,为什么方法[2]在我使用一个访问者但使用方法重载来调用正确的方