AutoValue / Gson的嵌套列表对象因NoSuchMethodError

时间:2017-05-24 00:47:44

标签: java gson auto-value

我正在尝试使用GSON将JSON对象转换为Java对象(使用AutoValue构建)。 JSON对象如下所示:

{
    "id": 1,
    "name": "Nutella Pie",
    "ingredients": [
        {
            "quantity": 2,
            "measure": "CUP",
            "ingredient": "Graham Cracker crumbs"
        },
        ...
    ],
    "steps": [
        {
            "id": 5,
            "shortDescription": "Finish filling prep"
        },
        ...
    ]
}

所以Java类(使用AutoValue构建)看起来像:

@AutoValue
public abstract class Recipe {
    @SerializedName("id")
    abstract int id();
    @SerializedName("name")
    abstract String name();
    @SerializedName("ingredients")
    abstract List<Ingredient> ingredients();
    @SerializedName("steps")
    abstract List<Step> steps();

    public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
        return new AutoValue_Recipe.GsonTypeAdapter(gson);
    }
}

create中的TypeAdapterFactory方法是:

public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
    Class<? super T> rawType = type.getRawType();

    if (rawType.equals(Ingredient.class)) {
        return (TypeAdapter<T>) Ingredient.typeAdapter(gson);
    }
    if (rawType.equals(Recipe.class)) {
        return (TypeAdapter<T>) Recipe.typeAdapter(gson);
    }
    if (rawType.equals(Step.class)) {
        return (TypeAdapter<T>) Step.typeAdapter(gson);
    }

    return null;
}

但是,我遇到了错误:

  

NoSuchMethodError:没有静态方法getParameterized

getParameterized是一种GsonTypeAdapter方法,显然未实施。

如果我将JSON和Java类更改为嵌套对象而不是嵌套对象列表,它可以正常工作

我不知道发生了什么事。有什么想法吗?

编辑: 我取得了一些进展。根据AutoValue GSON Extension docs

  

要支持具有泛型参数的字段(例如List),您需要将Gson依赖项升级到至少2.8.0,这将引入帮助程序TypeToken.getParameterized(),请参阅Gson Changelog。

这样,生成Type适配器的代码是:

public static <Ingredient,Step> TypeAdapter<Recipe<Ingredient,Step>> typeAdapter(Gson gson,
                  TypeToken<? extends Recipe<Ingredient,Step>> typeToken) {
    return new AutoValue_Recipe.GsonTypeAdapter(gson,typeToken);
}

但是,我在TypeAdapterFactory上使用它时遇到问题,因为它必须返回TypeAdapter<T>,而不是TypeAdapter<Recipe<Ingredient,Step>>。尝试铸造,但没有成功。

我该怎么办?添加一个新的TypeAdapterFactory?

1 个答案:

答案 0 :(得分:3)

  

NoSuchMethodError: No static method getParameterized

我假设您正在使用com.ryanharter.auto.value:auto-value-gson:0.4.6,但您拥有2.8.0之前的较旧Gson版本。您获得异常是因为AutoValue生成器在引擎盖下使用Gson 2.8.0,而Gson 2.8.0引入了TypeToken.getParameterized(请参阅commit 9414b9b3b61d59474a274aab21193391e5b97e52)。在运行时,JVM希望您的 Gson提供TypeToken.getParameterized方法。由于您似乎有较旧的Gson版本,因此会抛出错误。

在auto-value-gson documentation中还有关于Gson 2.8.0的说明:

  

您还需要gson本身的正常运行时依赖性。

     

compile 'com.google.code.gson:gson:2.8.0'

如果您正在使用Apache Maven,请确保您拥有最新的Gson:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.0</version>
</dependency>

这应该有效。如果由于某种原因无法升级Gson,请尝试降级AutoValue Gson生成器。