我有这些课:
class A implements Composite
{
Composite b = new B();
}
class B implements Composite
{
}
interface Composite
{
}
基本上
A
是由B
组成的,我想将它们保持这种组成形式存储在文件中。在活动中,我这样做:
String filename = "myfile.txt";
A a = new A();
Gson gson = new Gson();
String s = son.toJson(a);
FileOutputStream outputStream;
try
{
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(s.getBytes);
outputStream.close();
}
catch(Exception e)
{
}
然后,我使用此代码来阅读:
FileInputStream fileInputStream = null;
try
{
fileInputStream = openFileInput(filename);
}
catch(FileNotFoundException e)
{}
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)l;
BufferReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String line;
try
{
while((line = bufferedReader.readLine()) != null)
{
stringBuilder.append(line);
}
}
catch(IOException e)
{
}
String json = stringBuilder.toString();
Gson gson2 = new Gson();
// Exception here.
A a2 = gson2.fromJson(json, A.class);
问题出在类A内的对象B上。Gson似乎不知道
B
的类型。所以我得到这个异常:JNI在应用程序中检测到错误:无法使类型的对象
综合
最佳答案
问题在于接口没有属性,因此您需要序列化实现该接口的类。您需要使用构建器创建Gson实例
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Composite.class, new CompositeAdapter());
Gson gson = builder.create();
并定义代码以序列化您的Composite实例
public static class CompositeAdapter implements JsonSerializer<Composite>, JsonDeserializer<Composite> {
private static final String CLASSNAME = "CLASSNAME";
private static final String DATA = "DATA";
public Composite deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
String className = prim.getAsString();
Class klass = null;
try {
klass = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
// TODO: handle somehow
}
return jsonDeserializationContext.deserialize(jsonObject.get(DATA), klass);
}
public JsonElement serialize(Composite jsonElement, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty(CLASSNAME, jsonElement.getClass().getName());
jsonObject.add(DATA, jsonSerializationContext.serialize(jsonElement));
return jsonObject;
}
}
基本上,当序列化Composite实例时,它还将存储类名和属性,而反序列化时,它将创建实际类的实例(例如B)。这样,您不必担心为实现Composite的每个类创建序列化器和反序列化器,但是如果您更改类的名称(全名,包括程序包名称),将无法对其进行反序列化