You should always make defensive copies of stored mutable objects in your classes. You should always program defensively, assume that everyone that uses your class will break it.
This is demonstrated by the fact that although the class itself might be immutable, doesn't mean that objects in it are immutable too. You need to make defensive copies of mutable objects that you are using within your class.
Here's an example:
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!
This happens because the object MyClass only ever stored a pointer to the Point object that was passed in to it, which means that when the mutable object is changed - anything that points to that object is also changed. This can cause unintentional and unexepected results
To repair the above code, you make defensie copies of everything. It is important to note that copies should be made before any parameter checking occurs (e.g. validity check). You also need to make sure that your accessors are changed so that they too return copies of the internals of the class.
//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());
}
. . .
For the second part of your question - as long as BoundingBox
exists, the objects contained within it should exist too. The JVM wont garbage collect those until all references to them no longer exist.