2010-11-12 1 views
1

Посмотрите на следующий код, который я копирую с javax.naming.InitialContext. Аргумент типа HashTable передается конструктору. вот фрагмент кодаJava Code - Почему здесь клонируется переменная?

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

Мой вопрос, почему окружающая среда быть клонирована здесь, когда это могло быть передано непосредственно к инициализации методе?

ответ

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

+0

@ Не знаю, хороший совет. Готово. – jjnguy

+0

@ Невысокие шансы хороши, что единственное, о чем они беспокоятся, это дополнения или абсорбции. Вероятно, они используют неизменяемые объекты в качестве ключей или значений. – jjnguy

2

Потому что это может быть изменено с внешней стороны этого метода?