diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index 4196d9aa..4027d375 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -49,8 +49,10 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * This is the main class for using Gson. Gson is typically used by first constructing a @@ -897,11 +899,21 @@ public final class Gson { @Override public String toString() { - return new StringBuilder("{serializeNulls:") - .append(serializeNulls) - .append("factories:").append(factories) + return new StringBuilder("{serializeNulls:") + .append(serializeNulls) + .append("factories:").append(factories) .append(",instanceCreators:").append(constructorConstructor) .append("}") .toString(); } + + private final Set> generatedTypeAdapters = new HashSet>(); + public static final class $$Internal { + public static void addGeneratedTypeAdapter(Gson gson, TypeAdapter typeAdapter) { + gson.generatedTypeAdapters.add(typeAdapter); + } + public static boolean isGeneratedTypeAdapter(Gson gson, TypeAdapter typeAdapter) { + return gson.generatedTypeAdapters.contains(typeAdapter); + } + } } diff --git a/gson/src/main/java/com/google/gson/internal/bind/JsonAdapterAnnotationTypeAdapterFactory.java b/gson/src/main/java/com/google/gson/internal/bind/JsonAdapterAnnotationTypeAdapterFactory.java index 7163fe29..34f9d389 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/JsonAdapterAnnotationTypeAdapterFactory.java +++ b/gson/src/main/java/com/google/gson/internal/bind/JsonAdapterAnnotationTypeAdapterFactory.java @@ -43,15 +43,17 @@ public final class JsonAdapterAnnotationTypeAdapterFactory implements TypeAdapte Class clazz = targetType.getRawType(); JsonAdapter annotation = clazz.getAnnotation(JsonAdapter.class); if (annotation == null) return null; - TypeAdapter adapter = getAnnotationTypeAdapter(constructorConstructor, annotation); + TypeAdapter adapter = getAnnotationTypeAdapter(gson, constructorConstructor, annotation); return adapter; } - static TypeAdapter getAnnotationTypeAdapter( + static TypeAdapter getAnnotationTypeAdapter(Gson gson, ConstructorConstructor constructorConstructor, JsonAdapter annotation) { Class> adapterClass = annotation.value(); ObjectConstructor> constructor = constructorConstructor.get(TypeToken.get(adapterClass)); - return constructor.construct(); + TypeAdapter adapter = constructor.construct(); + Gson.$$Internal.addGeneratedTypeAdapter(gson, adapter); + return adapter; } } diff --git a/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java b/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java index cc9631a3..10295fc0 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java +++ b/gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java @@ -71,7 +71,9 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory { } ObjectConstructor constructor = constructorConstructor.get(type); - return new Adapter(constructor, getBoundFields(gson, type, raw)); + Adapter adapter = new Adapter(constructor, getBoundFields(gson, type, raw)); + Gson.$$Internal.addGeneratedTypeAdapter(gson, adapter); + return adapter; } private ReflectiveTypeAdapterFactory.BoundField createBoundField( @@ -99,14 +101,13 @@ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory { }; } - private TypeAdapter getFieldAdapter(Gson context, Field field, TypeToken fieldType) { - TypeAdapter adapter = context.getAdapter(fieldType); - // check if the registered adapter is a reflective type adapter. If so, JsonAdapter - // annotation should take precedence. Somewhat hackish, but works. - if (adapter instanceof Adapter && field.isAnnotationPresent(JsonAdapter.class)) { + private TypeAdapter getFieldAdapter(Gson gson, Field field, TypeToken fieldType) { + TypeAdapter adapter = gson.getAdapter(fieldType); + boolean generatedAdapter = Gson.$$Internal.isGeneratedTypeAdapter(gson, adapter); + if (generatedAdapter && field.isAnnotationPresent(JsonAdapter.class)) { JsonAdapter annotation = field.getAnnotation(JsonAdapter.class); return JsonAdapterAnnotationTypeAdapterFactory.getAnnotationTypeAdapter( - constructorConstructor, annotation); + gson, constructorConstructor, annotation); } return adapter; }