You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1.9 KiB
1.9 KiB
List 共享引用的风险分析
问题描述
在 Main.java 中,List<Article> articles 被传递给多个对象(CrawlerController、Command 等),这存在共享引用风险。
主要风险
1. 数据不一致风险
多个对象持有同一个 List 的引用,任何地方对 List 的修改都会影响其他地方。例如:
- CrawlCommand 添加了新 Article
- ListCommand 在遍历
- 如果同时修改,可能导致 ConcurrentModificationException
2. 封装性破坏
List 在多个类之间共享,违反了封装原则:
- 任何持有引用的类都可以随意修改 List
- 无法追踪是谁、在什么时候修改了数据
- 难以进行数据验证和完整性检查
3. 线程安全问题
如果未来引入多线程:
- 多个线程同时访问同一个 List
- 没有同步机制会导致数据损坏
- 可能出现脏读、丢失更新等问题
4. 测试困难
- 单元测试时难以隔离
- 一个测试可能影响另一个测试的结果
- 需要手动清理共享状态
解决方案
方案 1:使用不可变集合
// 返回不可变列表
public List<Article> getArticles() {
return Collections.unmodifiableList(articles);
}
方案 2:防御性拷贝
// 创建副本
public List<Article> getArticlesCopy() {
return new ArrayList<>(articles);
}
方案 3:使用 Repository 模式
// 通过 Repository 管理,不直接暴露 List
public class ArticleRepository {
private List<Article> articles = new ArrayList<>();
public void add(Article article) { }
public List<Article> findAll() {
return new ArrayList<>(articles); // 返回副本
}
}
总结
共享引用虽然方便,但会带来数据一致性、封装性、线程安全等问题。 最佳实践是:
- 最小化共享
- 必要时使用防御性拷贝
- 使用不可变集合
- 通过接口/Repository 封装访问
(字数:约 450 字)