fastjson泛型使用

本文介绍如何在Java中利用fastjson将JSON字符串转换成带有泛型的实体类,并通过一个具体的例子展示了正确的转换方法及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目开发中遇到一些实体类字段不确定的情况,就需要使用泛型或者继承了。
例如情况:一个json串分为head和body两部分,body中存在List,就是说这个List包含的内容不是确定的,这时候就需要使用泛型了。

在使用泛型定义实体类的时候,要注意在实体类的无惨构造函数中进行实例化,否则会出错。

    private Data<T> data;
    public Root() {
        data = new Data<T>();
        System.out.println("root 实例化");
    }
    private List<T> list ;
    public Data() {
        list = new ArrayList<T>();
        System.out.println("Data 实例化");
    }

我在项目中使用的fastjson转化的,遇到的一个困难是从json串转化为泛型实体类的时候,转化异常。在网上找到的解决方法是

Root<PlatCameraResList> root = 
    JSON.parseObject(json, new TypeReference<Root<PlatCameraResList>>(){});

解释一下:
Root: 就是需要转化的结果实体类
PlatCameraResList:就是我上面代码中的不确定类型T
TypeReference:是fastjson中的实体类,具体什么作用还没有细看

经过上面的代码转化,就能够将json串转化为你指定的泛型结果。

测试代码:

        @Test
    public void test2() {
        IpcService service = new IpcServiceImpl();
        int flag;
        try {

//          flag = service.IpcSynchro();

            String json = FilesUtil.readFile("C:\\Users\\fsky\\Desktop\\json.txt");
//          root = JSON.parseObject(json,root.getClass()); //适用于一般的对象转换
            Root<PlatCameraResList> root = JSON.parseObject(json, new TypeReference<Root<PlatCameraResList>>(){});//适用于泛型转换
            List<PlatCameraResList> pcl = new ArrayList<PlatCameraResList>();
            pcl = root.getData().getList();
            System.out.println(pcl);
            int i = 1;
            for(PlatCameraResList pc : pcl) {
                System.out.println(i + " -- 编码设备ID:" + pc.getEncoderId() + " -- 编码设备全局唯一标识:" + pc.getEncoderSysCode() +
                        " --- 监控点名称:" + pc.getCameraName() + " --- 监控点全局唯一标识:" + pc.getSysCode() + " --- 监控点ID:" + pc.getCameraId());
                i++;
            }


//          String str = "https://www.baidu.com/";
////            String response = PciUtil.sendGet(str, "java");
//          String response = PciUtil.sendPost(str);
//          System.out.println(response);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

测试结果:

Data 实例化
root 实例化
Data 实例化
[com.anxin.bulkload.web.model.ipcmodel.PlatCameraResList@1180c894, com.anxin.bulkload.web.model.ipcmodel.PlatCameraResList@1df07586]
1 -- 编码设备ID:3 -- 编码设备全局唯一标识:8cb44716be4c4c349171c11c42e189d4 --- 监控点名称:HD-Screen Controller_监控点 1 --- 监控点全局唯一标识:0d28212313cf4e4d95a5c5990a8b2b14 --- 监控点ID:1
2 -- 编码设备ID:3 -- 编码设备全局唯一标识:8cb44716be4c4c349171c11c42e189d4 --- 监控点名称:HD-Screen Controller_监控点 2 --- 监控点全局唯一标识:8385328ce46644fe9ee83aec07612831 --- 监控点ID:2

总结:
1,泛型实体类在创建对象的时候一定要实例化(很重要)
2,json串转换为泛型实体类,不能使用

root = JSON.parseObject(json,root.getClass()); //适用于一般的对象转换

而要用到

Root<PlatCameraResList> root = 
    JSON.parseObject(json, new TypeReference<Root<PlatCameraResList>>(){});

参考:
fastjson泛型如何转换

### Java 转换错误解决方案 在Java中,由于的不可变性和类擦除机制,可能会遇到一些常见的转换错误。为了更好地理解和解决问题,先了解几个核心概念。 #### 1. 不可变性 Java中的是不变的,这意味着`List<String>`不是`List<Object>`的子类[^1]。这种设计是为了防止破坏类安全性。例如: ```java // 这样做会引发编译错误 List<Integer> intList = new ArrayList<>(); List<Number> numList = intList; // 编译错误 ``` #### 2. 类擦除的影响 当涉及到继承关系时,通实例会在运行期间被替换为其原始类(即去掉所有的类参数)。这可能导致某些看似合理的赋值操作实际上无法工作[^2]。比如下面的例子展示了如何因为类擦除而导致问题: ```java public class Box<T> { private T content; public void setContent(T t) { this.content = t; } } Box<Integer> integerBox = new Box<>(); Box<Double> doubleBox = (Box<Double>)integerBox; // 可能抛出ClassCastException doubleBox.setContent(3.14); // 如果上面强制转换成功,则这里可能造成内存损坏 Integer value = integerBox.getContent(); // 将Double对象当作Integer处理 ``` 为了避免上述情况的发生,建议采取以下措施之一: - **使用通配符**:利用上下界(`? extends Type`, `? super Type`)来增加灵活性的同时保持类安全。 ```java List<? extends Number> numberList = Arrays.asList(1, 2L, 3.0); ``` - **引入中间变量或辅助函数**:有时可以通过创建临时容器或者编写专门的方法来进行必要的转检查。 - **避免不必要的转**:尽可能减少显式的类转换次数,尤其是在涉及复杂层次结构的地方。 最后值得注意的是,在FastAPI这样的现代Web框架里虽然也有类似的类提示功能用于定义响应体格式[^3],但这并不意味着可以直接将这些原则应用于底层语言特性如Java之上;两者属于不同层面的概念和技术栈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值