diff --git a/gson/src/main/java/com/google/gson/FieldNamingStrategy.java b/gson/src/main/java/com/google/gson/FieldNamingStrategy.java index b4c96c29c9..6cc8fc5787 100644 --- a/gson/src/main/java/com/google/gson/FieldNamingStrategy.java +++ b/gson/src/main/java/com/google/gson/FieldNamingStrategy.java @@ -16,6 +16,7 @@ package com.google.gson; +import com.google.gson.annotations.SerializedName; import java.lang.reflect.Field; import java.util.Collections; import java.util.List; @@ -35,13 +36,14 @@ public interface FieldNamingStrategy { * Translates the field name into its JSON field name representation. * * @param f the field object that we are translating - * @return the list of possible translated field names. + * @return the translated field name. * @since 1.3 */ public String translateName(Field f); /** - * Translates the field name into its JSON field alternative names representation. + * Translates the field name into its JSON field alternative names representation. used for + * deserialization only. This is similar to {@link SerializedName#alternate()}. * * @param f the field object that we are translating * @return the list of possible translated field names. 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 056583a6d7..d9337b9d9e 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 @@ -55,6 +55,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** Type adapter that reflects over the fields and methods of a class. */ public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory { @@ -87,9 +89,9 @@ private List getFieldNames(Field f) { SerializedName annotation = f.getAnnotation(SerializedName.class); if (annotation == null) { String fieldName = fieldNamingPolicy.translateName(f); - List fieldNames = new ArrayList<>(fieldNamingPolicy.translateToAlternateNames(f)); - fieldNames.add(fieldName); - return fieldNames; + List alternateNames = fieldNamingPolicy.translateToAlternateNames(f); + return Stream.concat(Stream.of(fieldName), alternateNames.stream()) + .collect(Collectors.toList()); } String serializedName = annotation.value(); diff --git a/gson/src/test/java/com/google/gson/functional/NamingPolicyTest.java b/gson/src/test/java/com/google/gson/functional/NamingPolicyTest.java index d41ed6a831..a1ddde6318 100644 --- a/gson/src/test/java/com/google/gson/functional/NamingPolicyTest.java +++ b/gson/src/test/java/com/google/gson/functional/NamingPolicyTest.java @@ -261,6 +261,32 @@ public List translateToAlternateNames(Field f) { assertThat(deserializedObject.someConstantStringInstanceField).isEqualTo("someValue"); } + @Test + public void testGsonWithAlternateNamesSerialization() { + Gson gson = + builder + .setFieldNamingStrategy( + new FieldNamingStrategy() { + + @Override + public String translateName(Field f) { + return "some-constant-string-instance-field"; + } + + @Override + public List translateToAlternateNames(Field f) { + return List.of("SomeConstantStringInstanceField"); + } + }) + .create(); + StringWrapper target = new StringWrapper("blah"); + assertThat(gson.toJson(target)) + .isEqualTo( + "{\"some-constant-string-instance-field\":\"" + + target.someConstantStringInstanceField + + "\"}"); + } + static final class AtName { @SerializedName("@foo") String f = "bar";