2010-11-12 41 views
1

看看下面的代码,我从复制javax.naming.InitialContext。 HashTable类型的参数正在传递给构造函数。这里是代码片段Java代码 - 为什么要在这里克隆一个变量?

public InitialContext(Hashtable<?,?> environment) throws NamingException 
{ 
    if (environment != null) { 
     environment = (Hashtable)environment.clone(); 
    } 
    init(environment); 
} 

我的问题是,为什么环境被克隆在这里时,它可以直接传递给init方法?

回答

6

此代码可以保护自己免受外部呼叫者更改HashTable的状态的影响。

通过制作clone它们,它们确保对传入的Hashtable所做的更改不反映在表传递到的方法/对象内部。

简单例子使用数组:

//Outside code 
int[] arr = new int[]{0, 1, 2, 3}; 

// method of class 
public void init(int[] arr) { 
    this.arr = arr; 
} 

//meanwhile, in the external code 
arr[0] = 42; // this change to the array will be reflected inside the object. 

即漏洞可以通过使数组的副本避免。对原始数组的更改不会显示在副本中。

+2

我想我会将你的第一句话改写为“此代码正在保护*本身*从外部调用者更改HashTable的状态。”尽管这是一个非常有限的保护,但是H'ashtable.clone()'是一个浅层克隆:调用者仍然可以更改可变值(我不记得上下文值是否仅限于字符串)。 – Anon 2010-11-12 15:48:58

+0

@Anon,很好的建议。完成。 – jjnguy 2010-11-12 15:50:44

+0

@Anon,他们唯一担心的是增加或删除的机会很大。他们可能使用不可变对象作为键或值。 – jjnguy 2010-11-12 15:52:01

2

因为它可以从这个方法的外部改变?