【问题标题】:Setter for arrays: public data assigned to private array数组的设置器:分配给私有数组的公共数据
【发布时间】:2015-10-08 12:23:37
【问题描述】:

https://cwe.mitre.org/data/definitions/496.html相关

谷歌搜索了一下,我发现我们不应该直接从公共 getter/setter 获取/设置私有数组。我们可以通过从 getter 返回数组的副本而不是实际数组来解决这个问题。对于 getter,我们可以将我们的私有数组分配给在 setter 中作为参数接收的数组的副本。

现在,我知道如果我们使用 getter,对数组的引用就会失效,并且可以随时修改。

private int[] arr = {1,2,3}; 
public int[] getArray() {
    return arr;
}

在其他可以访问该类的地方,这样做:

int[] badArray = obj.getArray();
badArray[0] = 100;

修改private arr。 我的问题是阵列会受到怎样的伤害。也就是说,如果我将 getter 修改为:

public int[] getArray() {
    return Arrays.copyOf(arr, arr.length);
}

并将我的二传手保持为:

public void setArray(int[] arr) {
    this.arr = arr;
}

这对我的私人阵列来说怎么可能有风险。请举例说明。 相关:Getters and setters for arrays

【问题讨论】:

  • 设置数组 -> 让应用程序继续运行 -> 更改在setArray(int[]) 中使用的数组 -> 应用程序损坏?换句话说,仅仅因为你(可能)修复了getArray,并不意味着我仍然不能操作我在setArray 中传递的数组。

标签: java arrays


【解决方案1】:

如果你保持你的 setter 为:

public void setArray(int[] arr) {
    this.arr = arr;
}

setter 的调用者持有对存储在您的类实例中的相同数组实例的引用,并且可以直接对其进行修改。

YourClass obj = new YourClass ();
int[] arr = new int[] {1,2,3};
obj.setArray (arr);
arr[0] = 5; // this will modify the array stored inside obj

如果您也可以在 setter 中创建数组的副本,则可以解决此问题:

public void setArray(int[] arr) {
    this.arr = Arrays.copyOf(arr, arr.length);
}

对于可变引用类型数组的更一般情况(与原始 int 数组示例不同),即使您阻止修改私有数组,仍然可以修改其引用保存在数组中的对象在你的班级之外(除非你的 setter 和 getter 也复制它们)。

【讨论】:

  • 地图和列表等数据结构也面临着类似的问题。那么我应该制作它们的完整副本并返回而不是返回对原始文件的引用吗?
  • @AkeshwarJha 您可以制作副本,也可以提供间接操作 Map/List 的方法。例如,您可以使用返回给定键值的get(key) 方法和返回键列表(或数组)的getKeyList() 方法,而不是返回映射的getMap 方法。如果你想提供改变地图的方法,你可以添加一个 add(key,value)` 方法(和类似的一个 remove 方法)。这样,您的类就可以控制对其内部 Map 的所有访问和修改。
  • 请再提出一个疑问。对于 getter 和 setter,克隆而不是 Arrays.copy 的效果如何?鉴于我只有原始数据类型的数组?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-09
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 2017-08-31
  • 2015-04-02
  • 1970-01-01
相关资源
最近更新 更多