如题,测试代码如下:
public static void main(String[] args) {
Foo x = test("{\"X\": \"x\", \"y\": \"y\"}");
}
@ToString
@Getter
@Setter
static class Foo {
private String x;
private String y;
}
// test1
private static <RESULT> RESULT test(String text) {
// return new Gson().fromJson(text, new TypeToken<RESULT>() {}.getType())
return JSONObject.parseObject(
text,
new TypeReference<RESULT>() {}.getType()
);
}
// test2
private static <RESULT> RESULT test(String text, RESULT result) {
// return new Gson().fromJson(text, new TypeToken<RESULT>() {}.getType())
return JSONObject.parseObject(
text,
new TypeReference<RESULT>() {}.getType()
);
}
我想使用 test 方法进行json
到RESULT
的转换,但是存在问题,调用这个方法的时候会报错,将Fastjson
替换成Gson
也会:
class com.alibaba.fastjson.JSONObject cannot be cast to class com.xx.xx.Xx
(com.alibaba.fastjson2.JSONObject and com.xx.xx.Xx are in unnamed module of loader 'app')
产生的原因我是知道的,但是不清楚为什么TypeReference
不起作用,那么对于这种场景,希望坚持使用泛型处理,可以做到吗?请指正。
1
zjp 2022-12-10 01:10:15 +08:00 via Android 1
感觉想复杂了
对于 test1 ,直接写 test("{\"X\": \"x\", \"y\": \"y\"}"); 显然 JVM 并不能知道 RESULT 应该是什么类 直接 JSONObject.parseObject(text, Foo.class)就好了 |
2
AoEiuV020CN 2022-12-10 01:36:21 +08:00 via Android 1
感觉误会了什么,
首先,答案是不可以,具体类型要么写死 Foo ,要么外面传进来, 如果有办法的话人家就直接封装好了,TypeReference 压根不会存在这么个东西,不会等你来想办法的, 根本上是 JAVA 的泛型擦除,运行时这个 RESULT 已经不存在了, 没有任何办法知道这个 RESULT 应该是什么, 比较友好一点的,比如 kotlin 就可以,有个 inline ,本质上就是你不用写,它自动帮你写上 Foo.class 代替泛型,于是就可以在方法内部获取到这个泛型类型, 但同样要求外面这个 Foo 必须是真实的类,不能是泛型, 最后 TypeReference 是针对 Map<String,List<Foo>这种复杂的类型,通过 TypeReference 生成子类间接获取到一个包含完整泛型信息的 Type , 必须有这个 Type 才能创建出对象,光有泛型不行, |
3
wangyu17455 2022-12-10 02:24:36 +08:00 1
java 拿不到对象的泛型,只能拿到字段的泛型,由于类型擦除,把 new ArrayList<String>作为参数传给一个方法,在运行时是没法通过反射得到泛型类型是 String 的,但是如果你定义一个泛型类,然后给方法传入 class ,就可以通过反射得到泛型类型了
|
4
xuanbg 2022-12-10 07:33:34 +08:00 1
Java 的泛型不能支持 OP 你这个操作,必须通过参数告诉反序列化方法你要反序列化成什么类型才行。所以,其实很简单,方法设计成这样就行了:public static <T> T toBean(String json, Class<T> type);
|
5
yazinnnn 2022-12-10 09:33:52 +08:00 1
inline fun <reified R> test(text: String): R {
return JSONObject.parseObject(text,R::class.java) } inline+reified 可以拯救一下 |
6
ufan0 OP @zjp #1
@AoEiuV020CN #2 @wangyu17455 #3 @xuanbg #4 @yazinnnn #5 谢谢各位,已经根据 4 楼建议成功处理。 还是我对 Class<>的使用不够熟悉,欸。 |
7
xuanbg 2022-12-11 10:40:24 +08:00
Class<SomeClass<T>>这种我没想出来怎么写,但应该是可以做到的。不传入类型,也应该是可以做到的。Rabbit MQ 可以自动将消息内容反序列化,spring web 也是一样能把 requist body 的 JSON 字符串反序列化成你指定的类型。
|
8
clownpiece 2022-12-11 12:46:05 +08:00
jackson 可以通过 mapper.readValue(string, mapper.getTypeFactory().constructParametricType(SomeClass.class, T.class))来实现
fastjson 因为不太熟,不清楚有没有对应的 |