Вы всегда должны делать защитные копии хранящихся изменяемых объектов в ваших классах. Вы всегда должны программировать с защитой, предполагая, что каждый, кто использует ваш класс, сломает его.
Это подтверждается тем фактом, что, хотя сам класс может быть неизменным, это не означает, что объекты в нем тоже неизменны. Вам нужно делать защитные копии изменяемых объектов, которые вы используете в своем классе.
Вот пример:
public class MyClass {
private Point foo;
private Point bar;
public MyClass(Point foo, Point bar) {
this.foo = foo;
this.bar = bar;
}
public Point foo() {
return foo;
}
public Point bar() {
return bar;
}
. . .
//Seems harmless enough?
//Lets destroy it
Point foo = new Point(1 ,2);
Point bar = new Point(3 ,4);
MyClass mc = new MyClass(foo, bar);
bar.x = 99; //<-- changes internal of mc!
Это происходит потому, что объект MyClass только когда-либо сохранял указатель на объект Point, который был передан ему, что означает, что при изменении изменяемого объекта - все, что указывает на этот объект, также изменяется. Это может привести к непреднамеренным и неожиданным результатам
Чтобы исправить приведенный выше код, вы делаете защитные копии всего. Важно отметить, что копии должны быть сделаны до того, как произойдет какая-либо проверка параметров (например, проверка достоверности). Вам также необходимо убедиться, что ваши методы доступа изменены, чтобы они также возвращали копии внутренних элементов класса.
//Fixed version!
public MyClass(Point foo, Point bar) {
this.foo = new Point(foo.getLocation());
this.bar = new Point(bar.getLocation());
}
public Point foo() {
return new Point(foo.getLocation());
}
public Point bar() {
return new Point(bar.getLocation());
}
. . .
Для второй части вашего вопроса - пока существует BoundingBox
, объекты, содержащиеся в нем, тоже должны существовать. JVM не будет собирать мусор до тех пор, пока не исчезнут все ссылки на них.