Tan*_*aus 54 java json casting gson
从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);
}
}
Run Code Online (Sandbox Code Playgroud)
从我的服务器,我得到一个ArrayList<Product>
JSON字符串表示.例如:
[{"mBarcode":"123","mName":"Apfel","mPrice":"2.7"},
{"mBarcode":"456","mName":"Pfirsich","mPrice":"1.1111"},
{"mBarcode":"89325982","mName":"Birne","mPrice":"1.5555"}]
Run Code Online (Sandbox Code Playgroud)
此String生成如下:
public static <T> String arrayToString(ArrayList<T> list) {
Gson g = new Gson();
return g.toJson(list);
}
Run Code Online (Sandbox Code Playgroud)
为了让我的对象回来,我使用这个函数:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是在打电话时
String name = Util.stringToArray(message).get(i).getName();
Run Code Online (Sandbox Code Playgroud)
我收到错误 com.google.gson.internal.LinkedTreeMap无法强制转换为object.Product
我究竟做错了什么?看起来它创建了一个LinkedTreeMaps列表,但我如何将它们转换为我的产品对象?
Ale*_* C. 85
在我看来,由于类型擦除,解析器无法在运行时获取实际类型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
}
Run Code Online (Sandbox Code Playgroud)
称之为:
String name = stringToArray(message, Product[].class).get(0).getName();
Run Code Online (Sandbox Code Playgroud)
wel*_*k91 15
我也有GSON抱怨有关CastTreeMaps的问题.
Alexis提供的答案和Aljoscha 的评论解释了错误发生的原因; "类型上的泛型通常在运行时被删除." 我的问题是我的代码在我正常运行时工作,但使用ProGuard导致代码被剥离,这对于强制转换至关重要.
你可以按照亚历克西斯的回答,更清楚地定义演员,这应该解决问题.您还可以添加Google提供的ProGuard 规则(只需执行此操作即可为我解决此问题).
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
Run Code Online (Sandbox Code Playgroud)
故事的道德:始终检查您需要的ProGuard规则.
类似于Alexis C的答案.但是在科特林.
只需将类类型传递给函数,并阐明泛型类型.
这是简化的例子.
inline fun <reified T> parseArray(json: String, typeToken: Type): T {
val gson = GsonBuilder().create()
return gson.fromJson<T>(json, typeToken)
}
Run Code Online (Sandbox Code Playgroud)
这是示例调用
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)
}
Run Code Online (Sandbox Code Playgroud)
小智 7
如果你ArrayList<MyObject>
在解析的时候在gson中使用自己的;
Type typeMyType = new TypeToken<ArrayList<MyObject>>(){}.getType();
ArrayList<MyObject> myObject = gson.fromJson(jsonString, typeMyType)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
60223 次 |
最近记录: |