Каков наилучший способ отправки защитной копии данных?
Я только что прочитал эффективное правило Java 39 (Защитная копия). В явном виде не указывается, что для каждой транзакции данных должно выполняться два раза копирования, чтобы следовать этому правилу. Ниже приведен пример кода, который я подумал. Это кажется несколько излишним. Я правильно понимаю? Есть ли лучший способ?
public class SomeClass {
private MyData myData;
SomeClass() {
myData = new MyData("1");
}
public MyData getData() {
return new MyData(myData); // 1st Copy of data
}
public static void main(String[] args) {
SomeClass someClass = new SomeClass();
OtherClass otherClass = new OtherClass(someClass.getData()); //Pass data which is invariant
}
}
class OtherClass {
MyData myData;
OtherClass(MyData data) {
myData = new MyData(data); // 2nd Copy of data
}
}
class MyData {
private String name;
public MyData(String name) { this.name = name; }
public MyData(MyData data) { this.name = data.name; }
public void setName(String name) { this.name = name; }
}
1 ответ
Ваше понимание верно, и конструктор, и метод делают защитные копии MyData
, Они делают это по несколько другим причинам, которые обсуждаются ниже.
Есть две причины сделать защитную копию:
- Защита от изменения входящих данных - вызывающий абонент передает вам объект и решает изменить его позже. Поскольку вы сделали защитную копию, изменения, внесенные вызывающей стороной, не влияют на данные, которые вы храните внутри, и
- Защита от изменения исходящих данных - вызывающая сторона может решить изменить объект, полученный одним из ваших методов. Поскольку вы вернули защитную копию своего объекта, ваши внутренние данные остаются в безопасности.
Код демонстрирует обе ситуации - OtherClass(MyData data)
конструктор демонстрирует проблему #1, в то время как MyData getData()
демонстрирует проблему № 2.
Обратите внимание, что защитные копии требуются только из-за решения сделать MyData
изменяемый класс (т.е. setName
метод). Нет необходимости делать защитные копии объектов неизменяемых классов.