我在序列化JSON数据时遇到了麻烦。
所以,我正在尝试使用泛型,但是当我尝试实现它时,Gson不知怎么讨厌我。 我所要做的就是用泛型进行基本的抽象。 这是我的代码:
执行泛型部分的主要类:
package com.yasinyazici.riot.config.json;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Map;
public abstract class JsonDataParser<T> {
protected Gson gson = new Gson();
protected String json;
public JsonDataParser(String json) {
this.json = json;
}
protected Map<String, T> transform() {
Type type = new TypeToken<Map<String, T>>(){}.getType();
return gson.fromJson(json, type);
}
public abstract T get();
}
这是主要班级的孩子:
package com.yasinyazici.riot.config.json.impl;
import com.yasinyazici.riot.config.json.JsonDataParser;
import com.yasinyazici.riot.data.summoner.SummonerProperties;
public class SummonerPropertiesParser extends JsonDataParser<SummonerProperties> {
public SummonerPropertiesParser(String json) {
super(json);
}
@Override
public SummonerProperties get() {
transform().entrySet().forEach(p -> System.out.println(p.getValue().getProfileIconId()));
return null;
}
}
如您所见,IntelliJ甚至将#get()识别为“SummonerProperties”。
这是我的错误:
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.yasinyazici.riot.data.summoner.SummonerProperties
at com.yasinyazici.riot.config.json.impl.SummonerPropertiesParser.lambda$get$0(SummonerPropertiesParser.java:17)
at java.lang.Iterable.forEach(Iterable.java:75)
at com.yasinyazici.riot.config.json.impl.SummonerPropertiesParser.get(SummonerPropertiesParser.java:17)
at com.yasinyazici.riot.Main.main(Main.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
我有点困惑。如果我打印p(对象本身),我会以一些奇怪的格式获得json
jungleíslife={id=8.2249757E7, name=Jungle ís Life, profileIconId=1339.0, summonerLevel=30.0, revisionDate=1.481558959E12}
原始json看起来像这样:
{"jungleíslife":{"id":82249757,"name":"Jungle ís Life","profileIconId":1339,"summonerLevel":30,"revisionDate":1481558959000}}
p#getValue()打印json的主体。 (以奇怪的格式)
所以似乎某些东西没有被正确解析。
任何?非常感谢任何帮助/解决方案。
编辑:这不完全是重复的,原因是我不是要尝试参数化任何类型,而是需要获取原始类型(我没有使用任何类用于访问类字段以进行解析的变量,我也不想这样做。
EDIT2:好的,好的。嗯,我尝试了选项1的示例(请参阅链接问题作为参考),但我得到以下内容(请注意,我在ListParameterizedType类中使用#getRawType()方法返回Map.class):
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
即使我让它继续返回ArrayList,它也会引发我的注意:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
编辑:仍有问题......
EDIT2:没有人有可能的解决方案..?
答案 0 :(得分:2)
您必须在子类中构造TypeToken,其中具体类型信息可用。向您的超类添加一个抽象方法:
protected abstract Type getType();
更改解析方法以使用它:
protected Map<String, T> transform() {
return gson.fromJson(json, getType());
}
然后在子类中重写getType
以返回具体类型:
@Override
protected Type getType() {
return new TypeToken<Map<String, SummonerProperties>>(){}.getType();
}
不相关,但您在打印getValue()
时看到的“怪异格式”不是json,而是来自Object.toString()
。