Use the same behavior in all situations when an InstanceCreator returns a subclass.
Previously we would set the field if the created instance is being assigned to a field of another object. We wouldn't set it when the created instance is a collection element or the top-level object.
This commit is contained in:
parent
4d0775ce8e
commit
8b21c7770b
@ -45,4 +45,11 @@ GSON 2.x lets the runtime throw a StackOverflowError
|
||||
com.google.gson.functional.CircularReferenceTest.testCircularSerialization
|
||||
com.google.gson.functional.CircularReferenceTest.testSelfReferenceSerialization
|
||||
com.google.gson.functional.CircularReferenceTest.testSelfReferenceArrayFieldSerialization
|
||||
com.google.gson.functional.CircularReferenceTest.testSelfReferenceCustomHandlerSerialization
|
||||
com.google.gson.functional.CircularReferenceTest.testSelfReferenceCustomHandlerSerialization
|
||||
|
||||
|
||||
GSON 1.x sometimes sets subclass fields when an InstanceCreator returns a subclass.
|
||||
This occurs only when the value is a field of another object: not when its
|
||||
the top level object or a collection element.
|
||||
GSON 2.x sets fields of the requested type only
|
||||
com.google.gson.functional.InstanceCreatorTest.testInstanceCreatorReturnsSubTypeForField
|
||||
|
@ -25,7 +25,6 @@ import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Field;
|
||||
@ -63,9 +62,7 @@ public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
}
|
||||
|
||||
ObjectConstructor<T> constructor = constructorConstructor.getConstructor(type);
|
||||
|
||||
return new Adapter<T>(context, constructor, type,
|
||||
getBoundFields(context, type, raw));
|
||||
return new Adapter<T>(constructor, getBoundFields(context, type, raw));
|
||||
}
|
||||
|
||||
private ReflectiveTypeAdapterFactory.BoundField createBoundField(
|
||||
@ -142,16 +139,11 @@ public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
}
|
||||
|
||||
public final class Adapter<T> extends TypeAdapter<T> {
|
||||
private final MiniGson context;
|
||||
private final ObjectConstructor<T> constructor;
|
||||
private final TypeToken<T> type;
|
||||
private final Map<String, BoundField> boundFields;
|
||||
|
||||
private Adapter(MiniGson context, ObjectConstructor<T> constructor,
|
||||
TypeToken<T> type, Map<String, BoundField> boundFields) {
|
||||
this.context = context;
|
||||
private Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) {
|
||||
this.constructor = constructor;
|
||||
this.type = type;
|
||||
this.boundFields = boundFields;
|
||||
}
|
||||
|
||||
@ -194,16 +186,6 @@ public class ReflectiveTypeAdapterFactory implements TypeAdapter.Factory {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: GSON includes subclass fields during serialization
|
||||
// if (false) {
|
||||
// Class<?> runtimeType = value.getClass();
|
||||
// if (runtimeType != type.getRawType()) {
|
||||
// TypeAdapter<?> adapter = context.getAdapter(runtimeType);
|
||||
// ((TypeAdapter) adapter).write(writer, value);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
writer.beginObject();
|
||||
try {
|
||||
for (BoundField boundField : boundFields.values()) {
|
||||
|
@ -77,6 +77,6 @@ public class InstanceCreatorTest extends TestCase {
|
||||
String json = "{base:{baseName:'Base',subName:'SubRevised'}}";
|
||||
ClassWithBaseField target = gson.fromJson(json, ClassWithBaseField.class);
|
||||
assertTrue(target.base instanceof Sub);
|
||||
assertEquals("SubRevised", ((Sub)target.base).subName);
|
||||
assertEquals(Sub.SUB_NAME, ((Sub)target.base).subName);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user