【问题标题】:StackOverflowError from Custom Moshi Adapter来自自定义 Moshi 适配器的 StackOverflowError
【发布时间】:2017-02-08 03:30:09
【问题描述】:

我创建了一个 moshi 适配器来处理空字符串值:

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

我用它创建了一个 Moshi 实例并将其添加到我的改造中:

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());
      }
    }
  }

为什么方法工厂会无休止地生成这些方法?

【问题讨论】:

    标签: java android retrofit stack-overflow moshi


    【解决方案1】:

    问题是您正在尝试将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;
      }
    }
    

    或者,如果您想强制执行此类型或反序列化从 json 解析的每个 String尽管我不建议这样做),您可以使用工厂声明您的适配器: p>

    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;
      }
    };
    

    【讨论】:

      猜你喜欢
      • 2018-06-17
      • 2017-03-09
      • 2017-03-18
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多