I want to make a getter that doesn't allow the caller to edit the returned object.
Using a List
as an example (though I would like the answer to apply to any other type as well), this is the usual approach for returning and for editing an attribute:
class MyClass {
private List<String> strings;
// to get the whole object
public List<String> getStrings() {
return this.strings;
}
// to alter the object
public void addString(String newStr) {
this.strings.add(newStr);
}
//...
}
However, this doesn't prevent that some other class from doing this
myClassInstance.getStrings().add("that's a dumb implementation, bro");
and that would be kind of rude since I created addString()
for that specific purpose.
I would rather if other classes would only use the getStrings()
method for reading, because there might be a similar case where I don't want to implement the addString()
method. In that situation, other classes are able to edit strings
anyway through the getter, but I still want to be able to edit the object privately in the C
class.
I know this wouldn't be a problem if the attribute was a primitive type since those are saved directly in the instance, but objects are references to memory, so any class that's able to get its hands on those references can edit it if the object type allows that.
Can I just trust that other classes won't try to edit my object through the getter?
There's the option of cloning it (some classes may override the
clone()
method), but is this a good use forclone()
? What are the best practices of cloning an object?Is it worth it to create a custom class (called
ReadOnlyList
, for this example) that is only writeable in the constructor (like this), then copy mystrings
to a newReadOnlyList
, and return that?Also, should objects provide a method that returns a non-writeable clone of the object to solve this?