我有一个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先前的配置解决了这个问题。