Saturday, 18 May 2013

Interview Question #11 How to make an object/class immutable and Why?

Background

This is a very interesting question. To give some background let me give an example - String Object in Java. You must have used it a lot but did you know that Strings are immutable. This means once you create a String object you cannot modify it.

Next obvious question that may arise is How do I get different String when I use methods like concat() or substring() ? The answer is you get a different String but not the modified one. Once desired operation is carried out and the result is computed a new String is created with this result and returned.You simply cannot edit a String instance which makes it immutable.

   Having the background information let us now get back to our original question - How can we make such an immutable object/class?

How to make an object/class immutable?

  • First thing that we can do is make the class itself final. This means this class cannot be sub classed any further. So you can start with - public final class Person{
    }
  •  Secondly make any data that you have in your class final. For example if you are creating a Person class  you can define name, age, DOB etc Final.

        final String name;
        final int age;
        final String DOB;
    

    Once this is done you can be sure that the data will not be modified once it is initialized. But how do we initialize the data? We cannot use setter methods as final data cannot be modified.Hence we go for 3rd point.
  • Now create a constructor with these data as arguments and initialize the data.
    Now your class will look like -


    public final class Person {
        private final String name;
        private final int age;
        private final String DOB;
    
        public Test(String name, int age, String DOB) {
            this.name = name;
            this.age = age;
            this.DOB = DOB;
        }
    }
    
This will make your class/object immutable. You can simple create object by saying Person p = new Person("John",21,"12/7/1991");
If you do not wish anyone to instantiate your class. You can provide a method like get public static Person getInstance(String name, int age, String DOB). Inside this function you can create an object of type Person and return it. You can also make your class singleton by checking if any instance already exists. There are many things you can do as per your implementation but the points mentioned above are sufficient to make a class/object immutable.

There can be more follow up questions like why would you make a class immutable?

Why prefer immutable object?

All atomicity and visibility issues that arise from multithreading are due such as race conditions, getting stale value, inconsistent state etc are due to multiple threads trying to access a mutable instance. If the instance is immutable these issue do not arise. Immutable objects are inherently thread safe.

NOTE :  Immutable objects are always thread safe.

Summary

  1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
  2. Make all fields final and private.
  3. 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.
  4. 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. 

Related Links

No comments:

Post a comment

t> UA-39527780-1 back to top