You need to enable JavaScript to run this app. Java调用FileDealer.modify方法二次执行时indexOf返回-1引发越界异常的解决
优惠活动
大模型
产品
解决方案
定价
更多

Java调用FileDealer.modify方法二次执行时indexOf返回-1引发越界异常的解决

问题根因拆解

这个报错本质不是真的数组越界,是indexOf()返回-1后没有做边界校验,直接调用List.get(-1)触发的异常,结合你的代码时序,问题的产生路径非常清晰:

  1. 程序初始化时,你拿到的t2是从FileDealer初始加载的ticketList中取出的,和列表内的对象是同一引用
  2. 第一次调用modify(t2, 0, "99999")时,因为是同一引用,indexOf()能正常匹配到索引,完成字段修改后,代码会执行updateFile()写回文件,随后无条件调用readFile()——这个方法一般是清空原有ticketList,从磁盘重新读取数据,生成一批全新的Ticket实例塞回列表,此时你原来持有的t2引用已经不在列表内了
  3. 第二次调用modify(t2, 0, "88888")时,indexOf()默认使用Object类的equals()方法(本质是比较对象内存地址)做匹配,因为列表里已经是新的Ticket实例,和旧的t2地址不一致,就会返回-1,后续直接调用get(-1)就触发了越界异常
修复方案

1. 为Ticket类重写equals与hashCode方法

不要依赖对象引用做匹配,基于业务上的唯一标识(比如mainID)定义对象相等规则,这样哪怕列表被重新加载,只要字段值匹配就能正常识别:

// 在Ticket类中添加
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Ticket ticket = (Ticket) o;
    // 用业务唯一字段做匹配,避免非唯一字段导致误匹配
    return Objects.equals(mainID, ticket.mainID);
}

@Override
public int hashCode() {
    return Objects.hash(mainID);
}

2. 给index查找结果增加边界校验

拿到索引后先判断有效性,不要直接调用get,避免无意义的底层越界异常,方便定位业务问题:

int index = ticketList.indexOf(t);
if (index == -1) {
    // 直接抛出明确的业务异常,替代底层的数组越界报错
    throw new IllegalArgumentException("未在工单列表中匹配到目标工单");
}
Ticket toModify = ticketList.get(index);

3. 移除modify方法末尾冗余的readFile调用

你现在每次修改完列表内容、写回文件后,没必要再全量从磁盘重新读一遍列表——既浪费IO性能,又会因为对象重建引发引用匹配问题。内存里的ticketList已经是修改后的最新状态,只需要保留updateFile()做持久化同步即可。
如果确实需要在修改后校验文件内容一致性,也要调整readFile()的逻辑:不要清空整个列表替换对象,改为增量同步字段、保持原有对象引用不变,避免触发匹配问题。

额外优化点

  • 当type为4执行删除操作时,不要在remove后继续操作被移除的对象,避免空指针
  • 不要提前将toModify初始化为null,直接在索引校验通过后初始化实例,减少不必要的空指针风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 09:36:05