From Effective Java 2/e by Joshua Bloch
Immutable Class?
An immutable class is simply a class whose instances cannot be modified
Immutable class examples
- String
- Boxed primitive classes
- BigInteger and BigDecimal
Advantage of immutable classes
- Easier to design, implement, and use
- Less prone to error and are more secure
Rules to follow to make immutable classes
- Don’t provide any methods that modify the object’s state
- Ensure that the class can’t be extended
- Make all fields final
- Make all fields private
- Ensure exclusive access to any mutable components
public final class Complex { private final double re; private final double im; public Complex(double re, double im) { this.re = re; this.im = im; } // Static factories instead of constructors // private Complex(double re, double im) { // this.re = re; // this.im = im; // } // // public static Complex valueOf(double re, double im) { // return new Complex(re, im); // } // Accessors with no corresponding mutators public double realPart() { return re; } public double imaginaryPart() { return im; } public Complex add(Complex c) { return new Complex(re + c.re, im + c.im); } public Complex subtract(Complex c) { return new Complex(re - c.re, im - c.im); } public Complex multiply(Complex c) { return new Complex(re * c.re - im * c.im, re * c.im + im * c.re); } public Complex divide(Complex c) { double tmp = c.re * c.re + c.im * c.im; return new Complex((re * c.re + im * c.im) / tmp, (im * c.re - re * c.im) / tmp); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Complex)) return false; Complex c = (Complex) o; // See page 43 to find out why we use compare instead of == return Double.compare(re, c.re) == 0 && Double.compare(im, c.im) == 0; } @Override public int hashCode() { int result = 17 + hashDouble(re); result = 31 * result + hashDouble(im); return result; } private int hashDouble(double val) { long longBits = Double.doubleToLongBits(re); return (int) (longBits ^ (longBits >>> 32)); } @Override public String toString() { return "(" + re + " + " + im + "i)"; } }
Advantages of immutable objects
- Immutable objects are simple
- Immutable objects are inherently thread-safe; they require no synchronization
- Immutable objects can be shared freely
public static final Complex ZERO = new Complex(0, 0); public static final Complex ONE = new Complex(1, 0); public static final Complex I = new Complex(0, 1);
- Not only can you share immutable objects, but you can share their internals
- Immutable objects make great building blocks for other objects (i.e. map, set)
- The only real disadvantage of immutable classes is that they require a separate object for each distinct value