Java and Immutability Part I

This how to explains the concept of immutibility using Java. The Webster's definition of immutibility seems a good place to start.

not capable of or susceptible to change

The goal of immutibility is make something unchangeable. Think of it as a "read-only" feature for programming. So once the object or variable is created, you can read it, but you can not change it.

Variable Immutibility Example

So to start here are some sample variables and objects.

 1 /* Example of Immutable Variables */
 2 import java.util.Date;
 3 import java.util.Calendar;
 4 import java.io.PrintWriter;
 5 
 6 class ImmutableVariables{
 7    
 8   public static void main(String[] args){
 9     PrintWriter pw = new PrintWriter(System.out, true);
10     
11     // Create a mutable Calendar Object
12     pw.println("\n== Demonstrate mutable Calendar Object ==");
13     Calendar cal = Calendar.getInstance();
14     pw.println("Start Date: " + cal.getTime());
15     cal.set(2010, 11, 31, 12, 00);
16     pw.println("Updated Date: " + cal.getTime());
17     
18     // Create an immutable String Object
19     pw.println("\n== Demonstrate immutable String Object ==");
20     String start = "Start String";
21     pw.println("start =  " + start);
22     start.replaceAll("Start", "Updated");
23     pw.println("start =  " + start);
24     

The code displayed above does two things. Lines 11 - 16 creates a Calendar object and changes the value of the Calendar. Lines 19 - 23 creates a String object and attempts to change it. When the program is run, the following output is produced.

== Demonstrate mutable Calendar Object ==
Start Date: Tue Jan 04 20:12:55 MST 2011
Updated Date: Fri Dec 31 12:00:55 MST 2010

== Demonstrate immutable String Object ==
start = Start String
start = Start String

A Calendar object is mutable and can be changed. Notice that it is changed after line 15 in the source is executed. The String object does not change. String objects are immutable. You can combine them and create new objects or assign references to them. But a String cannot be changed. When line 22 executes, nothing happens.

A Deeper Look at Strings

Very interesting. This whole string thing, deserves a deeper dive. In the following code the original string is copied. Then the String reference and String contents are compared.

25     // Change the String Reference
26     pw.println("\n== Copy String and Compare it ==");
27     pw.println("start = " + start);
28     String copy = start;
29     pw.println("String contents equal: " + copy.equals(start));
30     pw.println("String reference equal: " + (copy == start));
31     
32     pw.println("\n== Change Copy and Compare Strings ==");
33     start = new String("Start String"); 
34     pw.println("start = " + start);
35     pw.println("String contents equal: " + copy.equals(start));
36     pw.println("String reference equal: " + (copy == start) + "\n");    
37     

Notice on line 33, we make an exact duplicate of the original string. So what happens? Here is the output from the program.

== Copy String and Compare it ==
start = Start String
String contents equal: true
String reference equal: true

== Change Copy and Compare Strings ==
start = Start String
String contents equal: true
String reference equal: false

Notice that even thought the contents of the new object are identical, the reference is not. This is further proof that the String value cannot be changed. And thusly, a String is immutable.

This ends Part I of this immutability discussion in Part II, we examine how to make an object immutable.

Complete Source Code

ImmutableVariables.java (Click Here to View the Source Code Text)
   1 /* Example of Immutable Variables */
   2 import java.util.Date;
   3 import java.util.Calendar;
   4 import java.io.PrintWriter;
   5 
   6 class ImmutableVariables{
   7    
   8   public static void main(String[] args){
   9     PrintWriter pw = new PrintWriter(System.out, true);
  10     
  11     // Create a mutable Calendar Object
  12     pw.println("\n== Demonstrate mutable Calendar Object ==");
  13     Calendar cal = Calendar.getInstance();
  14     pw.println("Start Date: " + cal.getTime());
  15     cal.set(2010, 11, 31, 12, 00);
  16     pw.println("Updated Date: " + cal.getTime());
  17     
  18     // Create an immutable String Object
  19     pw.println("\n== Demonstrate immutable String Object ==");
  20     String start = "Start String";
  21     pw.println("start =  " + start);
  22     start.replaceAll("Start", "Updated");
  23     pw.println("start =  " + start);
  24     
  25     // Change the String Reference
  26     pw.println("\n== Copy String and Compare it ==");
  27     pw.println("start = " + start);
  28     String copy = start;
  29     pw.println("String contents equal: " + copy.equals(start));
  30     pw.println("String reference equal: " + (copy == start));
  31     
  32     pw.println("\n== Change Copy and Compare Strings ==");
  33     start = new String("Start String"); 
  34     pw.println("start = " + start);
  35     pw.println("String contents equal: " + copy.equals(start));
  36     pw.println("String reference equal: " + (copy == start) + "\n");    
  37     
  38   }
  39 }

References

There a couple of sources that really make this how-to possible.