【问题标题】:How do I avoid .clone()?如何避免 .clone()?
【发布时间】:2015-10-09 20:22:19
【问题描述】:

考虑这个类

class MyClass {
  private MyData[] data;

  public MyData[] getData() {
    return data == null ? null : (MyData[]) data.clone();
  }

这是造成问题

安全性 - 方法返回内部数组

直接暴露内部数组允许用户修改一些代码 这可能很关键。返回数组的副本更安全。

考虑到clone 不好,应该避免,我可以做些什么来使这段代码更好?

【问题讨论】:

  • 只复制数组?
  • System.arraycopyArrays.copyOf 都可以满足您的需求。
  • 你想在这里实现什么?只读数组?否则只返回数据本身。
  • @RalphWiggum 将返回一个浅拷贝。小心点。
  • 这看起来不是问题。并非所有警告都是问题,它们只是告诉您应该了解自己在做什么并接受您正在做的事情的后果。但不是问题。

标签: java arrays


【解决方案1】:

返回数组副本的最简单方法可能是调用Arrays.copyOf

public MyData[] getData() {
    return data == null ? null : Arrays.copyOf(data, data.length);
}

【讨论】:

  • @sᴜʀᴇsʜᴀᴛᴛᴀ Arrays#copyOf 在幕后使用System.arraycopy,这更容易调用/理解。
【解决方案2】:

我也同意克隆是不好的,但不是在阵列上。克隆在阵列上表现良好。您的代码很干净。保持原样。

很快我将附上关于数组克隆的 Josh Bloch 单词的参考。

Josh Bloch on Cloning

Doug Lea 走得更远。他告诉我他不再使用克隆,除了复制数组。 您应该使用 clone 来复制数组,因为这通常是最快的方法。但是 Doug 的类型不再实现 Cloneable 了。他已经放弃了。而且我认为这并非不合理。

如果你完全避免克隆,下一个最佳选择是

System.arraycopy(array1,0, array2, 0, array1.length);

因为

Arrays.copyOf 在内部创建另一个数组对象并将其返回,因为 System.arraycopy 使用传递的数组。

【讨论】:

  • 我会清除所有使用.clone 的代码并用正确的代码替换它。
  • @daydreamer 在这种情况下,System.arraycopy 是你的朋友。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 2010-12-07
  • 2013-02-12
  • 1970-01-01
  • 2011-05-15
  • 2014-05-30
  • 2022-01-26
相关资源
最近更新 更多