Gson RuntimeTypeAdapterFactory - 要序列化的null项导致空指针异常

时间:2015-01-03 21:57:42

标签: serialization gson

我正在测试RuntimeTypeAdapterFactoryTest:

https://code.google.com/p/google-gson/source/browse/trunk/extras/src/test/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactoryTest.java

在原始示例测试用例(testRuntimeTypeAdapter())中运行良好:

https://code.google.com/p/google-gson/source/browse/trunk/extras/src/test/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactoryTest.java#27

但是如果注册类型为null,我在RuntimeTypeAdapterFactory中得到一个NPE异常。扩展上面的原始示例:

static class Wallet {
    BillingInstrument payment;
}

Wallet wallet = new Wallet();
// wallet.payment = new Card("Jo", 123); // leave wallet.payment uninitialized.

gson.toJson(wallet); // throws NPE

如果我初始化wallet.payment,那么序列化工作正常。这是堆栈跟踪:

Exception in thread, java.lang.NullPointerException
at com.me.test.RuntimeTypeAdapterFactory$1.write(RuntimeTypeAdapterFactory.java:218)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:91)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:206)
at com.google.gson.Gson.toJson(Gson.java:595)
...

这里有哪些要点:

https://code.google.com/p/google-gson/source/browse/trunk/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java#218

有没有人碰到这个并找到了解决方法? Gson应该默认忽略序列化空值,所以不知道为什么它在我的例子中尝试序列化wallet.payment。

由于

2 个答案:

答案 0 :(得分:0)

陷入同样的​​问题。 这个修复对我有用:

(RuntimeTypeAdapterFactory.java)

           @Override public void write(JsonWriter out, R value) throws IOException {
            if(value!=null) {
                Class<?> srcType = value.getClass();
                String label = subtypeToLabel.get(srcType);
                @SuppressWarnings("unchecked") // registration requires that subtype extends T
                        TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
                if (delegate == null) {
                    throw new JsonParseException("cannot serialize " + srcType.getName()
                            + "; did you forget to register a subtype?");
                }
                JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
                if (jsonObject.has(typeFieldName)) {
                    throw new JsonParseException("cannot serialize " + srcType.getName()
                            + " because it already defines a field named " + typeFieldName);
                }
                JsonObject clone = new JsonObject();
                clone.add(typeFieldName, new JsonPrimitive(label));
                for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
                    clone.add(e.getKey(), e.getValue());
                }
                Streams.write(clone, out);
            }else{
                out.nullValue();
            }

答案 1 :(得分:0)

此问题已在this commit中修复,该问题发生在2.4版之前