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

向ArrayList添加非静态对象时部分存储值被覆盖的问题排查

问题排查:ArrayList中Song对象的流派被覆盖

核心问题:遍历XML生成Song对象并加入ArrayList后,所有Song的流派都被最后一次循环的内容覆盖,标题显示正常。

Song类定义

public class Song {
    private String title;
    private ArrayList<String> genre;
    public Song (String t, ArrayList<String> g) {
        title = t;
        genre = g;
    }
    public String getTitle () { return title; }
    public ArrayList<String> getGenre () { return genre; }
}

现象对比

预期输出

Song Title: 8 Genres:[metal,pop,balad]
Song Title: 11 Genres:[funk,pop]

实际输出

Song Title: 8 Genres: [funk,pop]
Song Title: 11 Genres:[funk,pop]

原因分析

问题出在循环中复用了同一个auxArray对象。ArrayList属于引用类型,你创建Song对象时传入的是auxArray的内存引用,而非内容副本。后续循环中对auxArray的修改(清空、添加新流派等操作),会直接同步到所有已创建的Song对象的genre列表中——因为它们指向的是同一个ArrayList实例。

解决方案

方案1:循环内创建新的auxArray

每次循环开始时初始化新的ArrayList,确保每首歌的genre对应独立的对象:

// 循环内部
while (遍历XML节点) {
    ArrayList<String> auxArray = new ArrayList<>(); // 每次循环新建
    // 填充当前歌曲的流派到auxArray
    Song song = new Song(title, auxArray);
    songsList.add(song);
}

方案2:创建Song时传入流派列表的副本

如果需要在循环外声明auxArray,可在创建Song时传入当前auxArray的副本,避免后续修改影响已生成的Song:

// 循环内部(auxArray在循环外声明)
auxArray.clear(); // 清空旧内容
// 填充当前歌曲的流派到auxArray
Song song = new Song(title, new ArrayList<>(auxArray)); // 传入副本
songsList.add(song);

优化建议:修改Song构造方法增强封装

可以在Song类的构造方法中主动复制传入的流派列表,从根源上避免外部引用修改影响内部状态:

public Song(String t, ArrayList<String> g) {
    title = t;
    genre = new ArrayList<>(g); // 创建独立副本,隔离外部修改
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:40:58