Monday, January 11, 2010

INTRO OF Data representation &Immutability IN JAVA

Data representation changes in scientific applications. Simple example: represent a point using Cartesian or polar coordinates. Polynomials (coefficents vs. point-value), matrices (sparse vs. dense).

Immutability.
An immutable data type is a data type such that the value of an object never changes once constructed. Examples: Complex and String. When you pass a String to a method, you don't have to worry about that method changing the sequence of characters in the String. On the other hand, when you pass an array to a method, the method is free to change the elements of the array.

Immutable data types have numerous advantages. they are easier to use, harder to misuse, easier to debug code that uses immutable types, easier to guarantee that the class variables remain in a consistent state (since they never change after construction), no need for copy constructor, are thread-safe, work well as keys in symbol table, don't need to be defensively copied when used as an instance variable in another class. Disadvantage: separate object for each value.

Josh Block, a Java API architect, advises that "Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, you should still limit its mutability as much as possible."

Give example where function changes value of some Complex object, which leaves the invoking function with a variable whose value it cannot rely upon.



mutable immutable
------------------------------------
Counter Complex
MovingCharge Charge
Draw String
array Vector
java.util.Date primitive types
Picture wrapper types


Final. Java provides language support to enforce immutability. When you declare a variable to be final, you are promising to assign it a value only once, either in an initializer or in the constructor. It is a compile-time error to modify the value of a final variable. public class Complex {
private final double re;
private final double im;

public Complex(double real, double imag) {
re = real;
im = imag;
}

// compile-time error
public void plus(Complex b) {
re = this.re + b.re; // oops, overwrites invoking object's value
im = this.im + b.re; // compile-time error since re and im are final
return new Complex(re, im);
}
}

It is good style to use the modifier final with instance variables whose values never change.
Serves as documentation that the value does not change.
Prevents accidental changes.
Makes programs easier to debug, since it's easier to keep track of the state: initialized at construction time and never changes.
Mutable instance variables. If the value of a final instance variable is mutable, the value of that instance variable (the reference to an object) will never change - it will always refer to the same object. However, the value of the object itself can change. For example, in Java, arrays are mutable objects: if you have an final instance variable that is an array, you can't change the array (e.g., to change its length), but you can change the individual array elements.

This creates a potential mutable hole in an otherwise immutable data type. For example, the following implementation of a Vector is mutable. public final class Vector {
private final int N;
private final double[] coords;

public Vector(double[] a) {
N = a.length;
coords = a;
}

...
}

A client program can create a Vector by specifying the entries in an array, and then change the elements of the Vector from (3, 4) to (0, 4) after construction (thereby bypassing the public API). double[] a = { 3.0, 4.0 };
Vector vector = new Vector(a);
StdOut.println(vector.magnitude()); // 5.0
a[0] = 0.0; // bypassing the public API
StdOut.println(vector.magnitude()); // 4.0

Defensive copy. To guarantee immutability of a data type that includes an instance variable of a mutable type, we perform a defensive copy. By creating a local copy of the array, we ensure that any change the client makes to the original array has no effect on the object. public final class Vector {
private final int N;
private final double[] coords;

public Vector(double[] a) {
N = a.length;

// defensive copy
coords = new double[N];
for (int i = 0; i < N; i++) {
coords[i] = a[i];
}
}

...
}

Program Vector.java encapsulates an immutable array.
Global constants. The final modifier is also widely used to specify local or global constants. For example, the following appears in Java's Math library. public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;

If the variables were declared public, a client could wreak havoc by re-assigning Math.PI = 1.0; Since Math.PI is declared to be private, such an attempt would be flagged as a compile-time error.

No comments:

Post a Comment