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

Java跨类克隆ArrayList时抛出IndexOutOfBoundsException异常

异常根因
  • 核心问题:Report类中直接通过new TaskPage()创建了一个全新的TaskPage实例,这个实例从未执行过你写的ArrayList数据填充逻辑,内部所有列表都是刚初始化的空列表(长度为0),此时调用get(0)访问第一个元素直接触发下标越界。你实际填充过数据的TaskPage实例和Report里new的这个空实例完全是两个独立对象,数据不互通。
  • 循环边界错误:ArrayList的合法下标范围是0 ~ 列表长度-1,你写的循环条件k <= tPage.tName.size()会让k最终等于列表长度,哪怕列表有数据,最后一次循环也会触发越界。
  • 语法逻辑错误:
    • 字符串值比较误用==:==比较的是两个对象的内存地址,不是内容,判断字符串相等必须用equals()方法。
    • 类型不匹配:你定义的taskDuration是ArrayList<String>类型,但原TaskPage中tDuration是ArrayList<Integer>,克隆强转时会抛出类型转换异常。
    • 结果赋值逻辑错误:循环中每次都直接给res赋新值,之前匹配到的内容会被覆盖,最终只能拿到最后一次循环的结果。
    • 无效克隆:你在init()方法里克隆了列表,但循环遍历的时候还是直接读tPage里的原始公共字段,克隆出来的列表完全没被使用。
修复方案
  • 第一步:修改Report类的实例持有逻辑,不要在Report内部new空的TaskPage,通过构造方法传入已经填充完数据的TaskPage实例,保证操作的是有真实数据的对象。同时修正taskDuration的泛型类型和原列表一致。
    public class Report {
        TaskPage tPage;
        public ArrayList<String> taskName;
        public ArrayList<String>  taskDesc;
        public ArrayList<String>  fLName;
        public ArrayList<String>  taskStatus;
        // 修正类型为Integer,和原列表匹配
        public ArrayList<Integer>  taskDuration;
        public ArrayList<String>  taskID;
      
        public String res = "";
    
        // 构造方法传入已存数据的TaskPage实例
        public Report(TaskPage page) {
            this.tPage = page;
        }
      
        public void init() {
            taskName = (ArrayList<String>)tPage.tName.clone();
            taskDesc = (ArrayList<String>)tPage.tDesc.clone();
            fLName = (ArrayList<String>)tPage.fLName.clone();
            taskStatus = (ArrayList<String>)tPage.tStatus.clone();
            taskDuration = (ArrayList<Integer>)tPage.tDuration.clone();
            taskID = (ArrayList<String>)tPage.tID.clone();
        }
    
  • 第二步:修正statusDone()方法的循环边界、字符串比较、结果拼接逻辑,同时使用克隆后的列表做遍历,避免原列表后续修改影响报表数据。
    public void statusDone() {
            init();
            res = "";
            // 修正循环条件为k < 列表长度,用克隆后的列表做遍历
            for (int k=0; k < taskName.size(); k++) {
                // 用equals比较字符串内容,常量放前面避免空指针
                if ("Done".equals(taskStatus.get(k))) {
                    // 用+=追加结果,不覆盖之前的匹配内容
                    res += fLName.get(k) + ", " + taskName.get(k) + ", " + taskDuration.get(k) + "\n";
                }
            }
            // 循环结束后如果没有匹配到任何已完成任务,再返回无数据提示
            if (res.isBlank()) {
                res = "There is nothing to display here!";
            }
        }
    }
    
  • 第三步:修改按钮点击事件的代码,创建Report实例时把当前页面持有真实数据的TaskPage对象传入。如果按钮逻辑就在TaskPage类里,直接传this即可:
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // 传入持有真实数据的TaskPage实例,不要让Report自己new空对象
        Report rpt = new Report(this);
        rpt.statusDone();
        String Status = rpt.res;
        JOptionPane.showMessageDialog(null, Status);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:09:18