Friday, June 22, 2012

User Defined Immutable Class - in short


/**
 * Code snippet to make user defined class as Immutable.
 *
 * Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
 * Make all fields final and private.
 * Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
 * A more sophisticated approach is to make the constructor private and construct instances in factory methods.
 * If the instance fields include references to mutable objects, don't allow those objects to be changed:
Don't provide methods that modify the mutable objects.
Don't share references to the mutable objects. Never store references to external,
mutable objects passed to the constructor; if necessary, create copies, and store references to the copies.
Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
 */
package com;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Thanooj
 *
 */

final class MyImmutableClass {

private final String firstName;
private final String lastName;
private List namesList;

public MyImmutableClass(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.namesList = new ArrayList();
this.namesList.add(this.firstName);
this.namesList.add(this.lastName);
}

public MyImmutableClass(String afirstName, String aLastName, String agender) {
this.firstName = afirstName;
this.lastName = aLastName;
this.namesList = new ArrayList();
if (agender.equalsIgnoreCase("MISS")) {
this.namesList.add("Miss.");
} else if (agender.equalsIgnoreCase("MISSES")) {
this.namesList.add("Misses.");
} else if (agender.equalsIgnoreCase("M")
|| agender.equalsIgnoreCase("MALE")) {
this.namesList.add("Mr.");
} else {
// nothing TO DO
}
this.namesList.add(this.firstName);
this.namesList.add(this.lastName);
}

public final String getFirstName() {
return firstName;
}

public final String getLastName() {
return lastName;
}

public final List getNamesList() {
/**
* Returns an unmodifiable view of the specified list. This method
* allows modules to provide users with "read-only" access to internal
* lists. if still we try to add elements into this List then it will
* throw an Exception - java.lang.UnsupportedOperationException at java
* .util.Collections$UnmodifiableCollection.add(Collections.java:1018)
*/
return Collections.unmodifiableList(namesList);
}

@Override
public String toString() {
StringBuilder nameBuilder = new StringBuilder();
for (String name : namesList)
nameBuilder = nameBuilder.append(name + " ");
return nameBuilder.toString();
}

}

public class ImmutableObjects {

/**
* @param args
*/
public static void main(String[] args) {

MyImmutableClass myImmutableClassOne = new MyImmutableClass("Srirama",
"Raghu", "M");
System.out.println(myImmutableClassOne);
MyImmutableClass myImmutableClassTwo = new MyImmutableClass("seeta",
"Raghu", "MISSES");
System.out.println(myImmutableClassTwo);
MyImmutableClass myImmutableClassThree = new MyImmutableClass(
"Lakhmana", "Raghu");
System.out.println(myImmutableClassThree);

  List names = myImmutableClassOne.getNamesList();
/**
* trying to add an element to an UnmodifiableCollection.
*/
names.add("throwAnException");

}

}
                                                           // Output :

No comments: