Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: wordsmithing + added code sample

Wiki Markup
Programmers sometimes incorrectly believe that declaring a field or variable {{final}} makes the referenced object immutable. Declaring variables that have a primitive type to be {{final}} does prevent changes to their values after initialization (other than through the use of the unsupported {{sun.misc.Unsafe}} class). However, when the variable has a reference type, the presence of a {{final}} clause in the declaration only makes _the reference itself_ immutable;. theThe {{final}} clause lackshas anyno effect whatsoever on the referenced object. Consequently, the fields of the referenced object can be mutable. For example, according to the Java Language Specification \[[JLS 2005|AA. Bibliography#JLS 05]\], [Section 4.12.4|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.4], "{{final}} Variables":

...

Similarly, a final method parameter obtains an immutable copy of the object reference; once again, this lacks any has no effect on the mutability of the referenced data.

...

Code Block
bgColor#ffcccc
class Point {
  private int x;
  private int y;

  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  void set_xy(int x, int y) {
    this.x = x;
    this.y = y;
  }
  void print_xy() {
    System.out.println("the value x is: " + this.x);
    System.out.println("the value y is: " + this.y);
  }
}

public class PointCaller {
  public static void main(String[] args) {
    final Point point = new Point(1, 2);
    point.print_xy();

    // change the value of x, y
    point.set_xy(5, 6);
    point.print_xy();
  }
}

...

When the values of the x and y members must remain immutable after their initialization, they should be declared final. However, this obviates the need for the setter method invalidates a set_xy() method, as it can no longer change the values of x and y.

Code Block
bgColor#ccccff
class Point {
  private final int x;
  private final int y;

  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  void print_xy() {
    System.out.println("the value x is: " + this.x);
    System.out.println("the value y is: " + this.y);
  }

  // set_xy(int x, int y) no longer possible
}

With this modification, the values of the instance fields become immutable and consequently match the programmer's intended usage model.

...

Code Block
bgColor#ccccff
final public class Point implements Cloneable {
  private int x;
  private int y;

  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  void set_xy(int x, int y) {
    this.x = x;
    this.y = y;
  }
  void print_xy() {
    System.out.println("the value x is: "+ this.x);
    System.out.println("the value y is: "+ this.y);
  }
  public Point clone() throws CloneNotSupportedException{
    Point cloned = (Point) super.clone();
    // No need to clone x and y as they are primitives
    return cloned;
  }
}

public class PointCaller {
  public static void main(String[] args) throws CloneNotSupportedException {
    final Point point = new Point(1, 2);
    point.print_xy();
    
    // Get the copy of original object
    Point pointCopy = point.clone();
    // pointCopy now holds a unique reference to the newly cloned Point instance

    // Change the value of x,y of the copy.
    pointCopy.set_xy(5, 6);

    // Original value remains unchanged
    point.print_xy();
  }
}

...

Code Block
bgColor#ffcccc
public static final String[] items = {/* ... */};

Clients can trivially modify the contents of the array, even though declaring the array reference to be final prevents modification of the reference itself.

Compliant Solution (Index Getter)

This noncompliant code example makes the array private, and provides a public methods to get individual items and array size

Code Block
bgColor#ffcccc

private static final String[] items = {/* ... */};

public static final String getItem(int index) {
  return items[index];
}

public static final int getItemCount() {
  return items.length;
}

Compliant Solution (Clone the Array)

...

Code Block
bgColor#ccccff
private static final String[] items = {/* ... */};

public static final String[] somethingsgetItems() {
  return items.clone();
}

...