2016-09-29 54 views
2

我創建了一個莫希適配器解決空字符串值:的StackOverflowError從自定義莫希適配器

public class NullStringAdapter { 
    @FromJson 
    public String stringFromJson(@Nullable String value) { 
     if (value.equals(null)) { 
      return "nulled"; 
     } 
     return value; 
    } 
} 

我創建了一個莫希實例與它並將其添加到我的改裝:

Moshi moshi = new Moshi.Builder().add(new NullStringAdapter()).build(); 
Retrofit.Builder().baseUrl(baseURL) 
     .addConverterFactory(MoshiConverterFactory.create(moshi)) 
     .client(client) 
     .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
     .build(); 

}

在運行時,我從MoshiAdapterMethodsFactory中的重複方法中得到一個StackOverflowError:

Caused by: java.lang.StackOverflowError: stack size 1038KB 
        at com.squareup.moshi.Moshi.cacheKey(Moshi.java:140) 
        at com.squareup.moshi.Moshi.adapter(Moshi.java:69) 
at com.squareup.moshi.AdapterMethodsFactory$5.fromJson(AdapterMethodsFactory.java:212) 
at com.squareup.moshi.AdapterMethodsFactory$1.fromJson(AdapterMethodsFactory.java:81)  
at com.squareup.moshi.AdapterMethodsFactory$5.fromJson(AdapterMethodsFactory.java:212) 
at com.squareup.moshi.AdapterMethodsFactory$1.fromJson(AdapterMethodsFactory.java:81)  
at com.squareup.moshi.AdapterMethodsFactory$5.fromJson(AdapterMethodsFactory.java:212) 
at com.squareup.moshi.AdapterMethodsFactory$1.fromJson(AdapterMethodsFactory.java:81) 

....等等。

兩個問題代碼區域是線212:

@Override public Object fromJson(Moshi moshi, JsonReader reader) 
     throws IOException, IllegalAccessException, InvocationTargetException { 
     JsonAdapter<Object> delegate = moshi.adapter(parameterTypes[0], qualifierAnnotations); 
     *****Object intermediate = delegate.fromJson(reader);***** 
     return method.invoke(adapter, intermediate); 
    } 

和線路81:

@Override public Object fromJson(JsonReader reader) throws IOException { 
    if (fromAdapter == null) { 
     return delegate.fromJson(reader); 
    } else if (!fromAdapter.nullable && reader.peek() == JsonReader.Token.NULL) { 
     reader.nextNull(); 
     return null; 
    } else { 
     try { 
     *****return fromAdapter.fromJson(moshi, reader);***** 
     } catch (IllegalAccessException e) { 
     throw new AssertionError(); 
     } catch (InvocationTargetException e) { 
     if (e.getCause() instanceof IOException) throw (IOException) e.getCause(); 
     throw new JsonDataException(e.getCause() + " at " + reader.getPath()); 
     } 
    } 
    } 

爲什麼方法工廠無休止生成這些方法?

回答

0

問題是,您正試圖將String改爲String,這就是創建循環的原因,因此導致StackOverflowError。創建所有你希望有"nulled"值的字符串自定義註釋,水木清華這樣的:

@JsonQualifier 
@Retention(RetentionPolicy.RUNTIME) 
public @interface NullableString { } 

,然後改變你的適配器:

public class NullStringAdapter { 
    @FromJson @NullableString 
    public String stringFromJson(@Nullable String value) { 
    if (value.equals(null)) { 
     return "nulled"; 
    } 
    return value; 
    } 
} 

或者,如果要強制執行這種類型或者你反序列化到每一個String從JSON解析(本書雖然我不會建議爲),你可以使用一個工廠聲明適配器:

public static final JsonAdapter.Factory FACTORY = new JsonAdapter.Factory() { 
    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { 
    if (!annotations.isEmpty()) return null; 

    Class<?> rawType = Types.getRawType(type); 
    if (rawType.equals(String.class) return /** your custom JsonAdapter here. */; 

    return null; 
    } 
};