Showing posts with label immutable. Show all posts
Showing posts with label immutable. Show all posts

Friday, September 16, 2011

Immutable Classes

Class whose instance object can not be modified are called immutable classes. In Java, Strings are best example of immutable classes. Though Java tackles Strings in differently manner but still they maintain the immutability of String class. In more technical terms, Immutable object are the objects whose state can not be changed.

What is the state of the object?
State of the object is value of its fields.

public class User {
String firstName;
String lastName;
public User(String firstName, String lastName, int identitiNumber) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

If you create instance of User class with Java as first name and Developer as last name, then userObject state is Java Developer.

But later you can change the last name to Programmer. So latest state would be Java Programmer. So in this case our class is mutable and it can alter the state based on the requirement.

What is an Immutable Object?
As mentioned earlier object whose state can not be altered is immutable object.

In Effective Java, Joshua Bloch makes this compelling recommendation :
"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."

How to create Immutable object/class?
To create immutable object prototype should be such that it should not provide a way to change the value once object has been created. Sun has defined one contract which should be followed to create immutable classes. Sun Immutable class contract.

Remove the setter methods.

public class User {
String firstName;
String lastName;
public User(String firstName, String lastName, int identitiNumber) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

Lets analyze if this solution will make the class immutable completely. Actually it will not. Because by default fields are visible to the class existing in same package. firstName and lastName are still exposed to classes in the same package. So it is still not safe.

Make all fields as private to the class


public class User {

private String firstName;

private String lastName;

public User(String firstName, String lastName, int identitiNumber) {

this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

Looks like we are safe now. But it does not look like. Though in our strings are immutable objects but lets say firstname and lastname are mutable objects. Then some one can take the reference of the object and change its property. So to by pass this problem, we will not return reference of the object but we will return cloned object.

Get should return cloned object


public class User {

private String firstName;

private String lastName;

public User(String firstName, String lastName, int identitiNumber) {

this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName.clone();
}
public String getLastName() {

return lastName.clone();

}

}



Make the class prototype final and all the final


Seems like class is safe and will do great. But to secure class/code secure from security threats and reflection uses we should mark class and its fields final. Generally class is marked as final so that any developer should not create any mutable class extending immutable class. If you are leaving this class non-final then java docs should provide basic purpose of leaving this non-final, so that developer extending the class should be sure about the complete feature of the class. For more information

Make the class prototype final and all the final


public final class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName, int identitiNumber) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

What are the advantages of Immutable object?
Okay, I have created immutable object. What next? How will it help me to improve my application? There are lot of questions that bugged me after creating first real immutable object. I search a little bit and most of the places suggest me thread safety is the biggest advantage of immutable classes. Lets figure out all possible advantage of immutable classes over mutable classes.

Thread Safe
When threads are sharing objects then it is mandatory to synchronize the shared object when state of shared object is changed by . In case of immutable objects we do not have any ways with which state of the shared object can be modified. So if multiple threads are sharing the same object, even then we do not have to worry about changes in shared data. As data for all the threads will remain consistent so there will not be any reading issues. So while writing thread code, we can use immutable object without any issue.

As immutable objects do not need additional protection at the time of thread handling, so additional efforts of synchronization will be by-passed. So application will become little faster than synchronized application.

Simple to construct, test, and use
Due to immutable behaviour of the object, these object are less error prone and can be tested easily. They are safe in threads so there are less complexity involved with the threads.

Do not need a copy constructor and clone
It is not required to create copy constructor for any immutable classes, because reference of the class will solve the purpose of copying.
For mutable classes copy constructor creates the copy of the existing object and later this copy can be altered as per the business need. Whereas in case of Immutable object user can not change the object, so instead creating the same object again, it is more advisable to return the same object.

Allow hashCode to use lazy initialization, and to cache its return value
Lazy initialization is the process to delay the process of instantiate/process something until it is necessary. So in case of immutable objects compiler need not to use hash code operation for each and every object until it is necessary. As hash code of the object will not change until the object remains in the memory, so hash code for the object can be cached for future references.

Do not need to be copied defensively when used as a field
It is not required to copy all the fields of the immutable object. As everything is unshakable so it is okay to return the reference of the object instead copying it deeply.

Make good Map keys and Set elements
As caching of the object's hashcode is possible so it makes better performing Maps and sets which internally uses hashing for faster access.

Always have failure atomicity
The transaction subtracts 10 from A and adds 10 to B. If it succeeds, it would be valid, because the data continues to satisfy the constraint. However, assume that after removing 10 from A, the transaction is unable to modify B. If the database retains A's new value, atomicity and the constraint would both be violated. Atomicity requires that both parts of this transaction complete or neither.

If an immutable object throws an exception, it's never left in an undesirable or indeterminate state.

What are the disadvantage of Immutable object?
So many advantage, then why caring about disadvantage. Why does every java developer not make all classes immutable? Why do we need mutable class when immutable are solving all the earthly and programmatic complexities. Anyways I believe we should know it. Following are few problematic areas of immutable objects.

Memory requirement

With immutability, any time you need to modify data, you need to create a new object. This can be expensive. Imagine needing to modify one bit in an object that consumes several megabytes of memory: you would need to instantiate a whole new object, allocate memory, etc. If you need to do this many times, mutability becomes very attractive.
Conclusion
As it is evident immutable object has lot of advantage over mutable object.Immutable objects (and more particularly, immutable collections) avoid all of these problems. Once you get your mind around how they work, your code will develop into something which is easier to read, easier to maintain and less likely to fail in odd and unpredictable ways. Immutable objects are even easier to test, due not only to their easy mock ability but also the code patterns they tend to enforce. In short, they're good practice all around!

Source/References(Used to write this post)


http://www.javalobby.org/articles/immutable/index.jsp

http://www.informit.com/articles/article.aspx?p=20530

http://www.javapractices.com/topic/TopicAction.do?Id=29

http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html
http://www.javaranch.com/journal/2003/04/immutable.htm
http://www.javalobby.org/articles/immutable/index.jsp
http://www.ibm.com/developerworks/java/library/j-jtp02183/index.html
http://en.wikipedia.org/wiki/Immutable_class
http://stackoverflow.com/questions/5652652/java-advantages-of-of-immutable-objects-in-examples

Friday, August 5, 2011

Java: Pass by Value

I was in an interview and interviewer asked me the following question.

public static void main(){
          String s1 = "A";
          s1 = s1 + 1;
          System.out.println("Before function call S1 is:" + s1);
          modifyString(s1);
          System.out.println("After function call S1 is:" + s1);
}

String modifyString(String a){
          a = a + 2;
          return a;
}

What is the output of the following problem?

Though I knew Java is pass by value but at the time of function call Java passes memory reference of the objects. So with the conviction I wrote the output of the program.

Before function call S1 is: A1
After function call S1 is: A12

Interview was over, I returned home, wrote the program and ran it in my eclipse. Bomb... It exploded. Results were not as I expected. WTF, why are those results not the same as I expected? I am the Java bond I can not be wrong. Instantaneously I pinged for an assistance. I wanted to hear "there is a problem with my eclipse instance. I should dump the current eclipse and take the latest eclipse soon." But instead hearing those words  I got following response.

Before function call S1 is: A1
After function call S1 is: A1

My expectation were shattered and I started arguing. Argument ended with my broken believe and I figured out "I have to cover a lot more about java fundamentals".

Anyways let me tell  you how does java pass the object to the function. In general java do not differentiate between Objects and primitive data type. It uses copy operation to pass the value of both type of data types.
If you have overridden copy method of your class then java will copy the object based of your implementation otherwise it will copy the object shallowly, in other words we say java uses shallow copy functionality of the objects. In case of shallow copy it creates a new reference to the object passed to the method. Now whenever you change in this method, are reflected back in the mutable classes, whereas in case of immutable classes it is not possible to change the object so we refrain ourselves to changing anything in those classes.

Lets review the following program.


public class PassByValueInJava {

int xy = 0;
private static void modifyPav(PassByValueInJava pav3 ,PassByValueInJava pav4) {
int temp  = pav3.xy;
pav3.xy = pav4.xy;
pav4.xy = temp;
}

public static void main(String[] args) {
PassByValueInJava pav1 = new PassByValueInJava();
PassByValueInJava pav2 = new PassByValueInJava();
pav1.xy = 10;
pav2.xy = 20;
System.out.println("Before Modify:::: pav1 x:" + pav1.xy + "   pav2 x:" + pav2.xy);
modifyPav(pav1, pav2);
System.out.println("After Modify::::pav1 x:" + pav1.xy + "   pav2 x:" + pav2.xy);
}

}


Can you guess what is the output of the program written here?
After seeing the above example I thought it should not switch the values. So results should be the following
Before Modify:::: pav1 x:10 pav2 x:20
After Modify:::: pav1 x:20 pav2 x:10

Now it is strange. Why did swapping happened? Was there something different?

Okay, lets analyze what has happened in this program? Main function calls the modify function and providing them the copy of pav1 and pav2. As copy is a shallow copy, so in this case Java will create a reference which will point to the same memory location of the previous object. Memory location depicts the situation well here.

Why did not same thing happened when string object was passed to the method.
As string in java are immutable so java deals with string in a different manner. Initially when S1 = A then string was pointing to one memory location and as soon as S1 = S1 + 1, it creates new string object and S1 was assigned to it.

Now when Main called modify function s1 was pointing to A1 memory location whose reference was passed to modify function. When string s2 got changed, then it started pointing to the A12 string object's memory location. But s1 is still pointing to the A1 string object's memory location. That is why value for s1 did not modify.

So it is clear that java always uses pass by value and as java tackles string in a complete different way, this is the reason we see such a huge difference between objects and strings.

Program mentioned above could enhance with the following


public static void main(){
          String s1 = "A";
          s1 = s1 + 1;
          System.out.println("Before function call S1 is:" + s1);
          s1 = modifyString(s1);
          System.out.println("After function call S1 is:" + s1);
}

String modifyString(String a){
          a = a + 2;
          return a;
}

It will result in the expected output.