@@ -26,34 +26,37 @@ public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
2626 // Check if the type adapter is a reflective, cause this solution only work for reflection.
2727 if (delegate instanceof ReflectiveTypeAdapterFactory .Adapter ) {
2828
29+ // This code is only compatible with GSON 2.11.0+
2930 try {
30- // Get reference to the existing boundFields.
3131 Class <?> adaptorClass = delegate .getClass ();
32- Field boundFieldsField = null ;
33- while (boundFieldsField == null && !adaptorClass .equals (Object .class )) {
32+ Field fieldsDataField = null ;
33+ while (fieldsDataField == null && !adaptorClass .equals (Object .class )) {
3434 try {
35- boundFieldsField = adaptorClass .getDeclaredField ("boundFields " );
35+ fieldsDataField = adaptorClass .getDeclaredField ("fieldsData " );
3636 } catch (NoSuchFieldException _ignore ) {
37- // Since GSON v3 .10, the internal class hierarchy has been changed
37+ // Since GSON v2 .10, the internal class hierarchy has been changed
3838 // 1) com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$FieldReflectionAdapter
3939 // 2) com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter
4040 adaptorClass = adaptorClass .getSuperclass ();
4141 }
4242 }
43- if (boundFieldsField == null ) {
44- String message = "Failed to find bound fields inside GSON" ;
43+ if (fieldsDataField == null ) {
44+ String message = "Failed to access fieldsData inside the GSON library " ;
4545 throw new IllegalStateException (message );
4646 }
47- boundFieldsField .setAccessible (true );
48- Map boundFields = (Map ) boundFieldsField .get (delegate );
47+ fieldsDataField .setAccessible (true );
48+ Object fieldData = fieldsDataField .get (delegate );
49+ Field deserializedFieldsField = fieldData .getClass ().getDeclaredField ("deserializedFields" );
50+ deserializedFieldsField .setAccessible (true );
51+ Map <String , ?> deserializedFields = (Map <String , ?>) deserializedFieldsField .get (fieldData );
4952 StringBuilder sb = new StringBuilder ();
50- for (Object key : boundFields .keySet ()) {
53+ for (String key : deserializedFields .keySet ()) {
5154 sb .append (key + ", " );
5255 }
53- final String boundFieldsStr = sb .append ("..." ).toString ();
56+ final String boundFieldsStr = sb .append ("... (" + type . getType (). getTypeName () + ") " ).toString ();
5457
5558 // Then replace it with our implementation throwing exception if the value is null.
56- boundFields = new LinkedHashMap ( boundFields ) {
59+ deserializedFields = new LinkedHashMap < String , Object >( deserializedFields ) {
5760
5861 @ Override
5962 public Object get (Object key ) {
@@ -68,7 +71,7 @@ public Object get(Object key) {
6871
6972 };
7073 // Finally, push our custom map back using reflection.
71- boundFieldsField .set (delegate , boundFields );
74+ deserializedFieldsField .set (fieldData , deserializedFields );
7275
7376 } catch (Exception e ) {
7477 // Should never happen if the implementation doesn't change.
0 commit comments