子类们的共同父类:BasePlugin
生成 Json ,子类信息都可以很好的输出
String json = new Gson().toJson(list);
但是,如果从 Json 中解析泛型类,它的子类的信息就获取不到,无法类型强转
Type type = new TypeToken<List<BasePlugin>>() {
}.getType();
return new Gson().fromJson(json, type);
这个有可能解决吗?
1
chendy 2023-07-07 08:20:25 +08:00
谷歌搜索 'gson type parameter' 第一条:
https://stackoverflow.com/questions/14139437/java-type-generic-as-argument-for-gson |
2
koloonps 2023-07-07 09:08:40 +08:00
new ObjectMapper().readValue("", new TypeReference<Object>() {
@Override public Type getType() { return super.getType(); } }) |
3
AoEiuV020JP 2023-07-07 10:08:47 +08:00
讲道理,仔细想想, 如果可以从父类泛型这样得到子类的属性,那人家直接内置一个,
Type type = new TypeToken<List<Object>>() { }.getType(); 压根都不需要暴露出 TypeToken 了, 这问题一定是无解的, 具体类型必须有个渠道提供给 json 框架, 加个 if else 判断然后 new 不同的 TypeToken 吧, 或者这个 type 改从外部传入, |
4
MozzieW 2023-07-07 10:17:16 +08:00
楼上的回复解决的范型 List ,OP 要的是范型 List+子类。
实践上,应该不能这么操作。解决范型 List 反序列话时候,我们是通过带入一个 Type 指定类型,解决类型丢失问题。而 OP 场景下,还多了一个子类型丢失问题。 最简单的方法,不要用子类,一个类接收全部参数,通过 type 区分行为,后续通过设计模式、switch 、if 代码 解决代码复用、逻辑问题。 其他方法:JSON 序列化时引入子类 type ,反序列化时先转为 map ,再根据 type 的值转为子类。 |
5
xiangyuecn 2023-07-07 10:42:33 +08:00
你实例化一个父类的实例,怎么可能会包含子类才有的属性🐶
|
6
shily 2023-07-07 11:18:59 +08:00 1
|
7
wqhui 2023-07-07 11:43:23 +08:00
反序列化的时候填了父类,解析的时候怎么知道你的子类有什么属性,或者说如果有一堆子类怎么知道装载成那个子类才是对的。
反序列化时需要想办法指定子类,比如参考 mongodb ,在序列化结果加上序列化的 class ,反序列化根据这个 class 来弄;比如在代码中使用注解标记 List 中的范型具体 class 是什么。 |
8
oneisall8955 2023-07-07 12:13:35 +08:00 via Android
|
9
Leon406 2023-07-07 12:45:41 +08:00
发下写的 gson 工具类, 可以参考
import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * <p>description:Gson 单例</p> * <p>author:Leon</p> * <p>date:2019/2/25 0025</p> * <p>e-mail: [email protected]</p> */ public class GsonUtils { private static final GsonUtils INSTANCE = new GsonUtils(); private Gson gson; private GsonUtils() { gson = new Gson(); } public static GsonUtils get() { return INSTANCE; } public Gson gson() { return gson; } public String toJson(Object obj) { return gson.toJson(obj); } public <D> D fromJson(String json, Class<D> clazz) { return gson.fromJson(json, clazz); } public <D> List<D> jsonToList(String json, Class<D[]> clazz) { D[] array = gson.fromJson(json, clazz); return Arrays.asList(array); } public <D> ArrayList<D> jsonToArrayList(String json, Class<D> clazz) { Type type = new TypeToken<ArrayList<JsonObject>>() { }.getType(); ArrayList<JsonObject> jsonObjects = gson.fromJson(json, type); ArrayList<D> arrayList = new ArrayList<>(); for (JsonObject jsonObject : jsonObjects) { arrayList.add(gson.fromJson(jsonObject, clazz)); } return arrayList; } } |
10
Helsing 2023-07-07 13:30:05 +08:00 via iPhone
可以换 kotlin 试试,有 reified 关键字
|
11
OpenJdk 2023-07-11 14:03:49 +08:00
不知道你用的什么 JSON 序列化工具。
|
12
OpenJdk 2023-07-11 14:07:53 +08:00
不知道你用的什么 JSON 序列化工具。
但是 Jackson 是通过在父类上打注解以字段值判定的形式来指定反序列化使用哪个具体的子类。 看看 @JsonTypeInfo 和 @JsonSubTypes 注解。 |