Re: How to "force" my object never been changed by other other objects using it?
www wrote:
I want myDataObj state never been modified by users.
You can't do it with any combination of "final" flags (unless you want to make
your object completely immutable -- and even then you can't /quite/ manage it).
The closest you can come is to hand out an immutable proxy for the object
instead of the object itself. E.g.
public interface Data
{
int getWidth();
String getName();
int[] getMoreData();
}
public class RealData
implements Data
{
private int m_width;
private String m_name;
private int[] m_moreData;
public int getWidth() { return m_width; }
public String getName() { return m_name; }
public int[] getMoreData() { return m_moreData; }
public void setWidth(int width) { m_width = width; }
public void setName(String name) { m_name = name; }
public void setMoreData(int[] data) { m_moreData = data; }
public Data asImmutableData() { return new ImmutableData(); }
class ImmutableData
implements Data
{
public int getWidth() { return RealData.this.getWidth(); }
public String getName() { return RealData.this.getName(); }
public int[] getMoreData() { return
RealData.this.getMoreData().clone(); }
}
}
Note that there may be nothing to gain in making RealData public, and there may
be nothing to gain in making it implement Data and have public get/set methods.
But I've made it public here to illustrate how, even if it is public, a user of
the object returned by asImmutableData() cannot change it.
Note also the call to clone() in the immutable version of getMoreData() -- we
don't want to hand out a reference to the real array, since arrays (or
references to arrays) cannot be made immutable.
As something of an aside, I would be tempted to add asImmutableData() to the
Data interface, and make ImmutableData.asImmutableData() just
return this;
The idea is that something can pass on an immutable proxy for a possibly
mutable object to a third party by using asImmutableData() whether originally
had a reference to a RealData or an ImmutableData.
A simpler solution, and in many cases a better solution, is just not to worry
about it. If the other code changes your object then it must have been given
the relevant access permissions -- and if you've given it that then you
obviously trust it not to do anything stupid.
-- chris