如何让fastjson2将数值数组反序列化为基本类型数组(非装箱列表)
问题
能否让fastjson2将JSON数组反序列化为float[]/int[]这类基本类型数组?要求避免数值的装箱/拆箱操作。目前尝试了JSONReader.Feature.UseDoubleForDecimals选项,但反序列化后得到的是JSONArray(本质是List)而非基本类型数组,且必须使用fastjson2,不能用Jackson。
测试代码如下:
void test() { enum TestEnum { A, B, C } // Prepare data Map<TestEnum, Object> testData = Map.of( TestEnum.A, "test", TestEnum.B, new String[]{"test1", "test2"}, TestEnum.C, new float[]{1.0f, 2.0f, 3.0f} ); // Serialize String serialized = JSON.toJSONString(testData); System.out.println("Serialized: " + serialized); JSONObject read = JSON.parseObject(serialized, JSONReader.Feature.UseDoubleForDecimals); for (Map.Entry<String, Object> stringObjectEntry : read.entrySet()) { System.out.println(stringObjectEntry.getKey() + " " + stringObjectEntry.getValue().getClass() + " " + (stringObjectEntry.getValue() instanceof List)); } System.out.println(read); }
执行输出:
Serialized: {"A":"test","C":[1.0,2.0,3.0],"B":["test1","test2"]} A class java.lang.String false C class com.alibaba.fastjson2.JSONArray true B class com.alibaba.fastjson2.JSONArray true {"A":"test","C":[1.0,2.0,3.0],"B":["test1","test2"]}
期望反序列化后,TestEnum.C对应的类型为float[]而非JSONArray。
解决方案
fastjson2默认将JSON数组解析为JSONArray,但可以通过指定目标类型的方式直接反序列化为基本类型数组,以下是几种可行方案:
方法1:手动转换已解析的JSONArray
如果已经得到JSONObject,可以调用JSONArray.toArray()方法直接将其转换为目标基本类型数组:
// 取出C对应的JSONArray JSONArray cArray = read.getJSONArray("C"); // 转换为float[] float[] floatArray = cArray.toArray(float[].class); System.out.println("C的类型:" + floatArray.getClass() + ",值:" + Arrays.toString(floatArray)); // 同理转换字符串数组 JSONArray bArray = read.getJSONArray("B"); String[] stringArray = bArray.toArray(String[].class);
这个方法直接基于已解析结果转换,无需重新反序列化,且避免了装箱拆箱操作。
方法2:定义实体类精准映射
创建匹配数据结构的实体类,明确字段为基本类型数组,fastjson2会自动完成类型映射:
class TestData { private String A; private String[] B; private float[] C; // 生成getter/setter public String getA() { return A; } public void setA(String a) { A = a; } public String[] getB() { return B; } public void setB(String[] b) { B = b; } public float[] getC() { return C; } public void setC(float[] c) { C = c; } } // 反序列化 TestData testData = JSON.parseObject(serialized, TestData.class, JSONReader.Feature.UseDoubleForDecimals); System.out.println("C的类型:" + testData.getC().getClass()); // 输出class [F(即float[])
这是最省心的方式,fastjson2会根据字段类型直接解析为对应数组,无需额外转换。
方法3:指定Map的泛型类型反序列化
如果必须使用Map,可以通过TypeReference声明泛型,同时开启枚举键支持特性:
// 声明目标类型的TypeReference TypeReference<Map<TestEnum, Object>> typeRef = new TypeReference<>() {}; // 反序列化时指定特性 Map<TestEnum, Object> resultMap = JSON.parseObject(serialized, typeRef, JSONReader.Feature.SupportEnumAsKey, JSONReader.Feature.UseDoubleForDecimals); // 对C的值进行类型转换 float[] cArray = ((JSONArray) resultMap.get(TestEnum.C)).toArray(float[].class);
注意这种方式下,Map中的数组值仍会被解析为JSONArray,需要手动转换为目标基本类型数组。
内容的提问来源于stack exchange,提问作者Enno Shioji
相关产品推荐
相关产品推荐

