You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:14:54