0

假设我有一个类,它接受一个 Key 对象数组来构造一个类 keyHandler 的对象,如下所示:

class KeyHandler {
    Key[] keys;
    public KeyHandler(Key[] keys) {
        this.keys=keys 
    }
    //more methods which modify key;
}

现在我从 main 调用这个构造函数

KeyHandler keyhandler = new KeyHandler(keys);

我想确保键数组不是从 main() 修改的。我怎样才能做到这一点?

4

4 回答 4

0

如果Key是不可变类,只需克隆数组:

this.keys = keys.clone();

如果Key对象不是不可变的,您将需要通过一一复制数组的元素来进行深度克隆。如果Key有一个复制构造函数,KeyHandler 构造函数可能如下所示:

this.keys = keys.clone();
for (int i = this.keys.length - 1; i >= 0; i--) {
    this.keys[i] = new Key(this.keys[i]);
}

您可以通过在网上搜索“防御性复制”来获取有关此做法的更多详细信息。

于 2012-12-12T13:41:09.970 回答
0

KeyHandler 类应该创建密钥数组的内部副本。然后就安全了。

class Keyhandler {    
   private Key[] keys;
   public KeyHandler(Key[] keys) {
      this.keys = new Key[keys.length]; 
      System.arrayCopy(keys, 0, this.keys, 0, keys.length); 
   }
     //more methods which modify key;
}

请注意,现在无法从外部操作键数组。但是仍然可以更改关键属性。为了绝对安全,您也应该克隆密钥。

于 2012-12-12T11:41:40.203 回答
0

最好的方法是在你的类中制作一个数组的副本:

this.keys = Arrays.copy(keys, keys.length);

但是请注意,如果Key对象是可变的并且您的 main 方法改变了您在数组中保存的键之一,那么您的本地副本也会观察到这种变化。为防止这种情况发生,您可以制作Key不可变对象或制作每个单独Key对象的副本(深拷贝)。

于 2012-12-12T11:42:13.000 回答
0

您可以通过对传递的数组进行深层复制来实现这一点。您使用 object.clone(); 创建深层副本;您可以进一步保护该数组免受外部更改,方法是不直接访问它,或者在 getArray(); 中返回数组的深层副本;您还可以考虑使用 Collections.unmodifiableList();

于 2012-12-12T11:44:42.873 回答