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

字节数组转换为Record对象集合出现NullPointerException问题求助

问题根因

  • Record类初始化顺序错误:Java类的成员变量初始化操作会先于构造函数执行,你声明idData、key时直接赋值,此时record成员还未被构造函数赋值,仍为null,调用Arrays.copyOfRange自然触发空指针异常。
  • 字节截取范围错误:long类型占8字节,对应区间应为[0,8)(Arrays.copyOfRange遵循左闭右开规则),你写的0-9实际截取了9字节,后续9-16仅截取7字节,不符合double类型占8字节的要求,即使修复空指针也会出现数据解析错误。
  • 转换函数循环边界错误:循环条件写为i <= byteArray.length,当i等于数组长度时,既会触发Arrays.copyOfRange下标越界,也会导致arrayRecords数组下标越界。

修复代码

修复后的Record类

public class Record {
    private final long idData;
    private final double key;

    public Record(byte[] recordArray) {
        // 入参长度校验,避免非法输入报错
        if (recordArray == null || recordArray.length != 16) {
            throw new IllegalArgumentException("Record字节数组长度必须为16");
        }
        // 在构造函数中完成解析,此时入参已完成赋值
        this.idData = ByteBuffer.wrap(recordArray, 0, 8).getLong();
        this.key = ByteBuffer.wrap(recordArray, 8, 8).getDouble();
    }

    // 按需添加getter方法
    public long getIdData() {
        return idData;
    }

    public double getKey() {
        return key;
    }
}

修复后的转换函数

public Record[] bytesToRecord(byte[] byteArray) {
    // 入参合法性校验
    if (byteArray == null || byteArray.length % 16 != 0) {
        throw new IllegalArgumentException("字节数组长度必须是16的整数倍");
    }
    int recordCount = byteArray.length / 16;
    Record[] arrayRecords = new Record[recordCount];
    // 按结果数组长度控制循环,避免越界
    for (int i = 0; i < recordCount; i++) {
        int offset = i * 16;
        arrayRecords[i] = new Record(Arrays.copyOfRange(byteArray, offset, offset + 16));
    } 
    return arrayRecords;
}

高频使用场景优化方案

如果转换操作调用频率极高,可以直接复用ByteBuffer避免频繁生成子数组,进一步提升性能:

// 高性能版转换函数
public Record[] bytesToRecordHighPerformance(byte[] byteArray) {
    if (byteArray == null || byteArray.length % 16 != 0) {
        throw new IllegalArgumentException("字节数组长度必须是16的整数倍");
    }
    int recordCount = byteArray.length / 16;
    Record[] arrayRecords = new Record[recordCount];
    ByteBuffer buffer = ByteBuffer.wrap(byteArray);
    // 如需指定字节序(大端/小端)可添加 buffer.order(ByteOrder.LITTLE_ENDIAN);
    for (int i = 0; i < recordCount; i++) {
        long id = buffer.getLong();
        double key = buffer.getDouble();
        arrayRecords[i] = new Record(id, key);
    }
    return arrayRecords;
}

配套在Record类中添加对应构造函数即可:

public Record(long idData, double key) {
    this.idData = idData;
    this.key = key;
}

内容的提问来源于stack exchange,提问作者Daniel Linares

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:24:02