java.net: Wiki

The Source for Java Technology Collaboration


 <<O>>  Difference Topic ImmutableObject (6 - 20 Jul 2004 - Main.hlovatt)
Line: 1 to 1
 
META TOPICPARENT name="JavaBeans"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 13 to 13
 
  • do not need an implementation of clone
  • do not need to be copied defensively when used as a field
  • make good Map keys and Set elements (these objects must not change state while in the collection)
Added:
>
>
 Make a class immutable by following these guidelines :
  • always put all data in the constructor, instead of using a no-argument constructor combined with subsequent calls to setXXX methods
Line: 88 to 89
 -- JohnOHanley - 19 Jul 2003
Changed:
<
<
Articles
>
>
Also see
 
Added:
>
>
 

<-- anchor to allow a link to the discussion about this article -->

 <<O>>  Difference Topic ImmutableObject (5 - 19 Jul 2004 - Main.hlovatt)
Line: 1 to 1
 
META TOPICPARENT name="JavaBeans"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 90 to 90
 Articles
Added:
>
>
 

<-- anchor to allow a link to the discussion about this article -->

 <<O>>  Difference Topic ImmutableObject (4 - 18 Jul 2004 - Main.sullis)
Line: 1 to 1
 
META TOPICPARENT name="JavaBeans"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 84 to 84
 }
Added:
>
>
 -- JohnOHanley - 19 Jul 2003
Added:
>
>
Articles
 

<-- anchor to allow a link to the discussion about this article -->

 <<O>>  Difference Topic ImmutableObject (3 - 23 Jul 2003 - Main.johanley)
Line: 1 to 1
 
META TOPICPARENT name="JavaBeans"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 90 to 90
 
<-- anchor to allow a link to the discussion about this article -->

Discussion about ImmutableObject
<-- generate a header for the discussion part of page -->

Added:
>
>
(An editor apparently disagrees strongly with PrivateMembersLast...)

-- JohnOHanley - 23 Jul 2003


 <<O>>  Difference Topic ImmutableObject (2 - 20 Jul 2003 - Main.zander)
Line: 1 to 1
 
META TOPICPARENT name="JavaBeans"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->
Line: 15 to 15
 
  • make good Map keys and Set elements (these objects must not change state while in the collection)

Make a class immutable by following these guidelines :

Changed:
<
<
  • always construct an object completely, instead of using a no-argument constructor combined with subsequent calls to setXXX methods
>
>
  • always put all data in the constructor, instead of using a no-argument constructor combined with subsequent calls to setXXX methods
 
  • do not provide any methods which can change the state of the object in any way - not just setXXX methods, but any method which can change state
  • ensure no methods can be overridden - make the class final, or use static factories and keep constructors private
  • make fields final
Line: 24 to 24
 Example
Added:
>
>
<-- changed some field names slightly to be more in sync with Java styleguides -->
 
import java.util.Date;
Line: 32 to 33
 * its state after construction. */ public final class Planet {
Added:
>
>
/** * Primitive data is always immutable. */ private final double mass;
 
Changed:
<
<
public Planet (double aMass, String aName, Date aDateOfDiscovery) { super(); fMass = aMass; fName = aName; //make a private copy of aDateOfDiscovery //this is the only way to keep the fDateOfDiscovery
>
>
/** * 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.) */ private final Date dateOfDiscovery;

/** Sole constructor */ public Planet (double mass, String name, Date dateOfDiscovery) { this.mass = mass; this.name = name; //make a private copy of dateOfDiscovery //this is the only way to keep the dateOfDiscovery

  //field private, and shields this class from any changes
Changed:
<
<
//to the original aDateOfDiscovery object fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
>
>
//to the original dateOfDiscovery object this.dateOfDiscovery = new Date(dateOfDiscovery.getTime());
  }

//gets but no sets, and no methods which change state public double getMass() {

Changed:
<
<
return fMass;
>
>
return mass;
  }

public String getName() {

Changed:
<
<
return fName;
>
>
return name;
  }

/**

Line: 60 to 79
  * class in any way. */ public Date getDateOfDiscovery() {
Changed:
<
<
return new Date(fDateOfDiscovery.getTime());
>
>
return new Date(dateOfDiscovery.getTime());
  }
Deleted:
<
<
// PRIVATE /////

/** * Primitive data is always immutable. */ private final double fMass;

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

/** * 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.) */ private final Date fDateOfDiscovery;

 }
Line: 92 to 90
 
<-- anchor to allow a link to the discussion about this article -->

Discussion about ImmutableObject
<-- generate a header for the discussion part of page -->

Deleted:
<
<

 <<O>>  Difference Topic ImmutableObject (1 - 19 Jul 2003 - Main.johanley)
Line: 1 to 1
Added:
>
>
META TOPICPARENT name="JavaBeans"
Home | Help | Changes | Index | Search | Go
<-- This creates the navigation links to :  Home | Help | Index | etc.  -->

Immutable Object

Objects have identity (location in memory), state (data), and behavior (methods). Once constructed, an Immutable Object cannot change state.

Immutable objects greatly simplify your program, since they

  • are simple to construct, test, and use
  • are automatically thread-safe and have no synchronization issues
  • do not need a copy constructor
  • do not need an implementation of clone
  • do not need to be copied defensively when used as a field
  • make good Map keys and Set elements (these objects must not change state while in the collection)

Make a class immutable by following these guidelines :

  • always construct an object completely, instead of using a no-argument constructor combined with subsequent calls to setXXX methods
  • do not provide any methods which can change the state of the object in any way - not just setXXX methods, but any method which can change state
  • ensure no methods can be overridden - make the class final, or use static factories and keep constructors private
  • make fields final
  • if a mutable object field's state is "owned" by the native class, such that no other class is to be allowed to change the state of the field, then when the field "crosses the interface" (as in a get method, when the field is returned to the user, or in the constructor itself), then a defensive copy must be made, in order to maintain encapsulation.
  • if a mutable object field's state is not "owned" by the native class, then defensive copies of the object field are not necessary

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 aMass, String aName, Date aDateOfDiscovery) {
     super();
     fMass = aMass;
     fName = aName;
     //make a private copy of aDateOfDiscovery
     //this is the only way to keep the fDateOfDiscovery
     //field private, and shields this class from any changes
     //to the original aDateOfDiscovery object
     fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
  }

  //gets but no sets, and no methods which change state
  public double getMass() {
    return fMass;
  }

  public String getName() {
    return fName;
  }

  /**
  * 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.
  */
  public Date getDateOfDiscovery() {
    return new Date(fDateOfDiscovery.getTime());
  }

  // PRIVATE /////

  /**
  * Primitive data is always immutable.
  */
  private final double fMass;

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

  /**
  * 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.)
  */
  private final Date fDateOfDiscovery;
}

-- JohnOHanley - 19 Jul 2003



<-- anchor to allow a link to the discussion about this article -->

Discussion about ImmutableObject
<-- generate a header for the discussion part of page -->


Topic ImmutableObject . { View | Diffs r6 < r5 < r4 < r3 | More }
 XML java.net RSS