Why getter & setter if return value is mutable?

ateiob picture ateiob · Sep 12, 2011 · Viewed 9.7k times · Source

In C++ a getter & setter for a private data member is very useful due to the ability to control mutability via a const return value.

In Java, if I understand correctly (please correct me if I am mistaken), specifying final on a getter doesn't work that way. Once the caller received the data member reference through the getter, it can modify it, despite it being private...

If that's the case (and please correct me if I have a gross misconception here), why not declare the data member public and simplify things?

Answer

Johan Sjöberg picture Johan Sjöberg · Sep 12, 2011

Making immutable return values in java is a matter of either returning already immutable objects types (such as String) or returning a copy for non-immutable objects.


Sample 1 - Already immutable object

public String getValue() {
    return value;
}

Sample 2 - Collection of already immutable objects

public List<String> getValues() {
    return new ArrayList<String>(values);
}

Sample 3 - Non-immutable object

public Complex getComplex() {
    return complex.clone();
}

Sample 4 - Collection of non-immutable objects

public List<Complex> getComplex() {
    List<Complex> copy = new ArrayList<Complex>(complexs.size());
    for (Complex c : complexs) 
        copy.add(c.clone());
    return copy;
}

Sample 3 and 4 are for conveniance based on that the complex type implements the Cloneable interface.

Furthermore, to avoid subclasses overriding your immutable methods you can declare them final. As a side note, the builder pattern is typically useful for constructing immutable objects.