Immutable objects

Immutable objects are simply objects whose state (the object's data) cannot change after construction. Examples of immutable objects from the JDK include String and Integer.

Immutable objects greatly simplify your program, since they:

Immutable objects have a very compelling list of positive qualities. Without question, they are among the simplest and most robust kinds of classes you can possibly build. When you create immutable classes, entire categories of problems simply disappear.

Make a class immutable by following these guidelines:

In Effective Java, Joshua Bloch makes this compelling recommendation :

"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."

It's interesting to note that BigDecimal is technically not immutable, since it's not final.

Example

import java.util.Date;

/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {

  public Planet (double mass, String name, Date dateOfDiscovery) {
     this.mass = mass;
     this.name = name;
     //make a private copy of aDateOfDiscovery
     //this is the only way to keep the fDateOfDiscovery
     //field private, and shields this class from any changes that 
     //the caller may make to the original aDateOfDiscovery object
     this.dateOfDiscovery = new Date(dateOfDiscovery.getTime());
  }

  /**
  * Returns a primitive value.
  *
  * The caller can do whatever they want with the return value, without 
  * affecting the internals of this class. Why? Because this is a primitive 
  * value. The caller sees its "own" double that simply has the
  * same value as fMass.
  */
  public double getMass() {
    return mass;
  }

  /**
  * Returns an immutable object.
  *
  * The caller gets a direct reference to the internal field. But this is not 
  * dangerous, since String is immutable and cannot be changed.
  */
  public String getName() {
    return name;
  }

//  /**
//  * Returns a mutable object - likely bad style.
//  *
//  * The caller gets a direct reference to the internal field. This is usually dangerous, 
//  * since the Date object state can be changed both by this class and its caller.
//  * That is, this class is no longer in complete control of dateOfDiscovery.
//  */
//  public Date getDateOfDiscovery() {
//    return dateOfDiscovery;
//  }

  /**
  * Returns a mutable object - good style.
  * 
  * Returns a defensive copy of the field.
  * The caller of this method can do anything they want with the
  * returned Date object, without affecting the internals of this
  * class in any way. Why? Because they do not have a reference to 
  * fDate. Rather, they are playing with a second Date that initially has the 
  * same data as fDate.
  */
  public Date getDateOfDiscovery() {
    return new Date(dateOfDiscovery.getTime());
  }

  // PRIVATE

  /**
  * Final primitive data is always immutable.
  */
  private final double mass;

  /**
  * An immutable object field. (String objects never change state.)
  */
  private final String name;

  /**
  * A mutable object field. In this case, the state of this mutable field
  * is to be changed only by this class. (In other cases, it makes perfect
  * sense to allow the state of a field to be changed outside the native
  * class; this is the case when a field acts as a "pointer" to an object
  * created elsewhere.)
  *
  * java.util.Date is used here only because its convenient for illustrating 
  * a point about mutable objects. In new code, you should use 
  * java.time classes, not java.util.Date.
  */
  private final Date dateOfDiscovery;
}
 

Note that javadoc 1.4 includes the -tag option, whereby simple custom tags may be defined. One might define an @is.Immutable tag, for example, to document a class as being immutable.

You might also consider defining your own tag interface for immutable objects.

See Also :
Validate state with class invariants
Copy constructors
Defensive copying
Factory methods
Use final liberally
Implementing hashCode
Lazy initialization
Document thread safety
Avoid JavaBeans style of construction
Model Objects
Tag or marker interfaces
Know the common sources of complexity