在Java中返回内部集合的最佳实践是什么?

Eri*_*erg 11 java collections

我很好奇从可变类返回一组对象时被认为是更好的做法:

public class Someclass {

  public List<String> strings;  

  public add(String in){ strings.add(in); }
  public remove(String in) { strings.remove(in); }   

  //THIS
  public List<String> getStrings(){
    return Collections.unmodifiableList(strings);
  }

  //OR THIS
  public List<String> getStrings(){
    return new ArrayList(strings);
  }
}
Run Code Online (Sandbox Code Playgroud)

我总是假设将内部集合包装在Unmodifiable中是最好的方法,因为我没有理由产生创建副本的开销.但是,我发现内部对列表所做的任何更改都会暴露给客户端,这对我来说是糟糕的.

Ste*_*n C 6

我不认为这有一个简单的"最佳实践"答案.这实际上取决于您愿意花费多少机器资源来防止违反类数据抽象边界.这取决于你实际上试图减轻的风险; 例如,它是简单(非并发)错误,并发错误还是信息泄漏.

选项是:

  • 没做什么; 即按原样返回集合.
  • 返回包装在不可变包装类中的集合.
  • 返回集合的浅表副本.
  • 返回该集合的深层副本.

除了复制的直接成本之外,其他与性能相关的因素还有内存使用和垃圾生成以及对并发性的影响.例如,如果多个线程正在更新集合和/或"获取"它,那么制作集合的副本通常涉及锁定它......这可能会使操作成为并发瓶颈.

总之,您需要在不采取预防措施的情况下平衡成本/性能影响与潜在或实际风险和成本.