diff --git a/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java b/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java index 24fc0862..104b8b42 100644 --- a/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java +++ b/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java @@ -124,6 +124,16 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor { } } else { Object fieldValue = getFieldValue(f, obj); + // See if the fieldValue has better type information than the specified typeOfF + // This takes care of situations where the field was declared as an Object, but the + // actual value contains something more specific. See Issue 54. + if (fieldValue != null && typeOfF instanceof Class) { + Class classOfF = (Class) typeOfF; + Class actualClassOfF = fieldValue.getClass(); + if (classOfF.isAssignableFrom(actualClassOfF)) { + typeOfF = actualClassOfF; + } + } addAsChildOfObject(f, typeOfF, fieldValue); } } diff --git a/gson/src/test/java/com/google/gson/functional/ObjectTest.java b/gson/src/test/java/com/google/gson/functional/ObjectTest.java index 99c62843..bce9637b 100644 --- a/gson/src/test/java/com/google/gson/functional/ObjectTest.java +++ b/gson/src/test/java/com/google/gson/functional/ObjectTest.java @@ -361,6 +361,21 @@ public class ObjectTest extends TestCase { assertEquals(target.getExpectedJson(), gson.toJson(target)); } + /** + * Tests that a class field with type Object can be serialized properly. + * See issue 54 + */ + public void testClassWithObjectFieldSerialization() { + ClassWithObjectField obj = new ClassWithObjectField(); + obj.member = "abc"; + String json = gson.toJson(obj); + assertTrue(json.contains("abc")); + } + + private static class ClassWithObjectField { + Object member; + } + public void testInnerClassSerialization() { Parent p = new Parent(); Parent.Child c = p.new Child(); @@ -371,7 +386,8 @@ public class ObjectTest extends TestCase { public void testInnerClassDeserialization() { final Parent p = new Parent(); - Gson gson = new GsonBuilder().registerTypeAdapter(Parent.Child.class, new InstanceCreator() { + Gson gson = new GsonBuilder().registerTypeAdapter( + Parent.Child.class, new InstanceCreator() { public Parent.Child createInstance(Type type) { return p.new Child(); }