PMD имеет правило под названием ArrayIsStoredDirectly в безопасности солнца ruleset:
Конструкторы и приемные антенные решетки методов должны клонировать объекты и сохранить копию. Это предотвращает то будущее изменения от пользовательского влияния внутренняя функциональность.
Вот их пример:
public class Foo {
private String [] x;
public void foo (String [] param) {
// Don't do this, make a copy of the array at least
this.x=param;
}
}
Я не думаю, что полностью понимаю обоснование позади этого правила. Это, потому что значения в массиве передали, может быть изменен где-то в другом месте? Существует ли различие между передачей Набора по сравнению с передачей массива в отношении этого?
Проблема в том, что вызывающий может сохранить копию переданного им аргумента массива, а затем может изменить его содержимое. Если объект критичен с точки зрения безопасности и вызов осуществляется из ненадежного кода, у вас есть брешь в безопасности.
В этом контексте передача коллекции и ее сохранение без копирования также может представлять потенциальную угрозу безопасности. (Я не знаю, есть ли правило PMD, чтобы сообщить вам об этом.)
В обоих случаях способ устранения риска (если он реальный) состоит в том, чтобы установить для атрибута копию массива или коллекции аргументов. . С другой стороны, если вы знаете, что код вызывающей стороны всегда будет доверенным, копирование будет пустой тратой времени, и лучшим решением было бы сказать PMD, чтобы он не молчал об этом конкретном методе.
Нет разницы между передачей коллекции или массива: в обоих случаях отправитель и получатель могут изменять содержимое структуры данных. Вот пример:
// ... in some method
Foo myfoo = new Foo();
String[] array = {"One", "Two", "Three"};
myfoo.foo(array); // now the Foo instance gets {"One", "Two", "Three"}
array[1] = "Changed"; // now the internal field x in myfoo is {"One", "Changed", "Three"}
Если вам не нужно такое поведение, вы должны, следуя этому правилу PMD, клонировать массив в Foo и сохранить ссылку на клон. Таким образом вы убедитесь, что ни один другой класс не содержит ссылку на ваш внутренний массив (если мы не забудем на мгновение об отражении и если мы не вернем этот внутренний массив другим методом ...)