com.google.gson.internal.LinkedTreeMap 不能投射到我的类

2022-08-31 11:14:41

我从JSON字符串获取对象时遇到了一些问题。

我上了课Product

public class Product {
    private String mBarcode;
    private String mName;
    private String mPrice;

    public Product(String barcode, String name, String price) {
        mBarcode = barcode;
        mName = name;
        mPrice = price;
    }

    public int getBarcode() {
        return Integer.parseInt(mBarcode);
    }

    public String getName() {
        return mName;
    }

    public double getPrice() {
        return Double.parseDouble(mPrice);
    }
}    

从我的服务器,我得到了一个在JSON字符串表示。例如:ArrayList<Product>

[{"mBarcode":"123","mName":"Apfel","mPrice":"2.7"},
{"mBarcode":"456","mName":"Pfirsich","mPrice":"1.1111"},
{"mBarcode":"89325982","mName":"Birne","mPrice":"1.5555"}] 

此字符串的生成方式如下:

public static <T> String arrayToString(ArrayList<T> list) {
    Gson g = new Gson();
    return g.toJson(list);
}

要取回我的对象,我使用这个函数:

public static <T> ArrayList<T> stringToArray(String s) {
    Gson g = new Gson();
    Type listType = new TypeToken<ArrayList<T>>(){}.getType();
    ArrayList<T> list = g.fromJson(s, listType);
    return list;
}

但是在打电话时

String name = Util.stringToArray(message).get(i).getName();

我得到错误 com.google.gson.internal.LinkedTreeMap 无法转换为对象。产品

我做错了什么?它看起来像是创建了一个LinkedTreeMaps列表,但是我如何将它们转换为我的产品对象?


答案 1

在我看来,由于类型擦除,解析器无法在运行时获取真正的类型T。一种解决方法是将类类型作为参数提供给方法。

像这样的东西是有效的,当然还有其他可能的解决方法,但我发现这个非常清晰和简洁。

public static <T> List<T> stringToArray(String s, Class<T[]> clazz) {
    T[] arr = new Gson().fromJson(s, clazz);
    return Arrays.asList(arr); //or return Arrays.asList(new Gson().fromJson(s, clazz)); for a one-liner
}

并称其为:

String name = stringToArray(message, Product[].class).get(0).getName();

答案 2

类似于亚历克西斯C的答案。但是在科特林。
只需将类类型传递到函数中,并阐明什么是泛型类型。
下面是一个简化的示例。

inline fun <reified T> parseArray(json: String, typeToken: Type): T {
    val gson = GsonBuilder().create()
    return gson.fromJson<T>(json, typeToken)
}

下面是示例调用

fun test() {
    val json: String = "......."
    val type = object : TypeToken<List<MyObject>>() {}.type
    val result: List<MyObject> = parseArray<List<MyObject>>(json = json, typeToken = type)
    println(result)
}