diff --git a/gson/src/main/java/com/google/gson/ReflectingFieldNavigator.java b/gson/src/main/java/com/google/gson/ReflectingFieldNavigator.java index 0e88b77f..863fc790 100644 --- a/gson/src/main/java/com/google/gson/ReflectingFieldNavigator.java +++ b/gson/src/main/java/com/google/gson/ReflectingFieldNavigator.java @@ -74,7 +74,7 @@ final class ReflectingFieldNavigator { } @SuppressWarnings("unchecked") - private Type getMoreSpecificType(Type type, Object obj, FieldAttributes fieldAttributes) { + private static Type getMoreSpecificType(Type type, Object obj, FieldAttributes fieldAttributes) { try { if (obj != null && (Object.class == type || type instanceof TypeVariable)) { Object fieldValue = fieldAttributes.get(obj); diff --git a/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapter.java index 55855d5d..9ffc9b9d 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapter.java @@ -21,6 +21,7 @@ import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.util.LinkedHashMap; import java.util.Map; @@ -122,7 +123,11 @@ public final class ReflectiveTypeAdapter extends TypeAdapter { @Override void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException { Object fieldValue = field.get(value); - ((TypeAdapter) typeAdapter).write(writer, fieldValue); + Type declaredTypeOfField = fieldType.getType(); + Type resolvedTypeOfField = getMoreSpecificType(declaredTypeOfField, value, fieldValue); + TypeAdapter t = resolvedTypeOfField != declaredTypeOfField ? + context.getAdapter(TypeToken.get(resolvedTypeOfField)) : this.typeAdapter; + t.write(writer, fieldValue); } @Override void read(JsonReader reader, Object value) throws IOException, IllegalAccessException { @@ -132,6 +137,15 @@ public final class ReflectiveTypeAdapter extends TypeAdapter { }; } + private static Type getMoreSpecificType(Type type, Object obj, Object fieldValue) { + if (obj != null && (Object.class == type || type instanceof TypeVariable)) { + if (fieldValue != null) { + type = fieldValue.getClass(); + } + } + return type; + } + public static class FactoryImpl implements Factory { public boolean serializeField(Class declaringClazz, Field f, Type declaredType) { return true;