This is not a problem if the object returned is immutable - that is, is cannot be changed because it has no methods to change its state (and, of course, its instance variables are all private). Integer, String, and Character are examples of existing immutable classes.
The problem with immutable objects, of course, is that the object whose state they represent often needs to change them! MarkRobinson? has described a solution to this, using an AdapterPattern.
Define a pair of interfaces, one which is immutable, and one which extends it and allows state changes. Define a class which implements each of these interfaces. The immutable implementation has a pointer to the mutable one, and delegates all accessor methods to it, which the mutable one is used only by the owning object.
For example:
public interface PolarPoint? { public double getRadius(); public double getAngle(); }This is a lot more work than the alternative ReturnNewObjectsFromAccessorMethods, but it avoids the need to constantly create new objects on the heap on each method call.public interface MutablePolarPoint? extends PolarPoint? { public void setRadius( double radius ); public void setAngle( double angle ); }
public class ImmutablePolarPoint? implements PolarPoint? { public ImmutablePolarPoint?( MutablePolarPoint? point ) { _state = point; } public double getRadius() { return _state. getRadius(); } public double getAngle() { return _state. getAngle(); } }
-- RussellGold
void test( ImmutablePolarPoint? p ) { System.out.println( p.getRadius() - p.getRadius() ); }This won't always print 0, because behind the scenes is a MutablePolarPoint? which another thread could be modifying.
True immutability makes makes it much easier to analyse code statically, for correctness and for optimisation, and its especially important in a multi-threaded environment like Java. -- DaveHarris
For example there's the following inheritance hierarchy:
* NSString ----> NSMutableString * NSString ----> NSImmutableStringwhere NSString is an abstract class.
Accessor methods for complex value objects always return objects of type NSString. Because the object's class might be NSMutableString, the returned objects might be mutable.
This means the classes have the following semantics:
* NSString: A string that might change but you can't change. * NSMutableString: A string that you can change. * NSImmutableString: A string that never changes.If you want to keep a NSString object, you have to make a copy from it. The NSImmutableString's copy method just returns itself, NSMutableString makes a real copy.
-- Constantin Szallies
This page mirrored in JavaIdioms as of April 29, 2006