我有一个ArrayList <GeneralTemplate> items
在我的程序中,我添加的例程是generaltemplate的子类,即items.add(new Routine("Test"));,一切正常。
最重要的是,我可以做到以下几点。Routine myRoutine = items.get(position);
我正在使用google的gson库将这个大项目列表保存在json中的一个特殊数据对象中。我相信这可能是问题所在。
此数据对象包含ArrayList <GeneralTemplate> items。在我的程序中,我可以看到存储在items列表中的例程确实是Routine对象。然后我用下面的代码保存它。我用调试器遵循了这个过程,当我设置routinelist时,例程对象就可以毫无问题地维护了。

// Global save String method
public static void save()
{
    Editor editor = sharedPreferences.edit();

    RoutineData tempSaveObject = new RoutineData();
    tempSaveObject.setRoutineList(routineList);

    String routineListInJSON = gson.toJson(tempSaveObject);

    editor.putString(ROUTINE_LIST, routineListInJSON).commit();
}

当我重新启动应用程序并检索数据时,就会出现问题。列表中的所有项都将还原为GeneralTemplate对象,并且无法通过Routine>Routine routine = (Routine) items.get(position)将其还原为ClassCastException(下面的加载代码)
    // Get a global sharedPreferences object that can be used amongst Activities
    sharedPreferences = this.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE);

    if (sharedPreferences.contains(ROUTINE_LIST))
    {
        String routineListJSON = sharedPreferences.getString(ROUTINE_LIST, null);
        routineDataObject = gson.fromJson(routineListJSON, RoutineData.class);

        routineList = routineDataObject.getRoutineList();
    }
    else
    {
        routineList = new ArrayList<GeneralTemplate>();
    }

因此,我无法访问特定的方法和变量,因为我无法重新获得子类上下文。这个问题还有其他几个例子,所以如果有什么好的解决方案,你们这些好人知道的话,它会有很大帮助。
谢谢!
排序:
genson json库。
https://code.google.com/p/genson/downloads/detail?name=genson-0.94.jar&can=2&q=
使事情变得如此简单,不需要自定义序列化器/反序列化器。默认情况下处理所有深入的多态性。
实现如eugen的答案所示

最佳答案

这是因为您有一个generaltemplate列表,而序列化gson知道列表中每个元素的具体类型,但是在反序列化期间gson不知道要反序列化到哪种类型(因为它是generaltemplate列表)。
我不确定,但看起来他们有一些contrib(不是gson的一部分)允许在序列化流中添加类型信息,这允许gson反序列化回正确的类型。
您也可以尝试Genson库,它支持即时处理多态类型。它具有gson和其他一些公司提供的功能。以下是您实现这一目标的方法:

// first configure your Genson instance to enable polymorphic types support and
// serialization based on concrete types
Genson genson = new Genson.Builder()
                            .setWithClassMetadata(true)
                            .setUseRuntimeTypeForSerialization(true)
                            .create();

// and now just use it to serialize/deser
String json = genson.serialize(routineData);
RoutineData data = genson.deserialize(json, RoutineData.class);

编辑
问题解决了。例程类没有默认构造函数。将@jsonproperty(“name”)放在ctr参数上并使用gensons先前的配置解决了这个问题。

07-26 09:42