2010-11-12 60 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

因爲它可以從這個方法的外部改變?