Sunday, 2 March 2014

Immutable and Final

It is a known fact that String objects are immutable? What does this mean? Does this mean that String objects are implicitly final?

  • String objects are indeed immutable. Now, this means that once a String object has been initialized, it's state cannot be changed.

String str = "India". Once such an assignment has been made, you can consider the heap allocated with an object "India" as shown with str being the reference.



Now, if we make an assignment, str = "China", what we are in fact doing is reassigning str to another object, China on the heap.




Here, the reference str has changed value. It was formerly pointing to object with state "India" and now it has been reassigned to refer to object with state, "China". In fact, the assignment of form, str = "somestring" creates a new string object on the heap each time. This is why String object is said to be immutable, immutable in that once initialized with a value, it can never change its state.

  • What if we had initialized with the final keyword:  final String str = "India"?

What we have done now is made the reference str immutable. 'Immutable' may not be the best choice of a word here for what I had intended to say was that we have made the reference a constant, constant in that it will now point to the object "India" on the heap and can never be reassigned to refer to any other object on the same. In fact, the statement, str = "China" is now illegal.

  • Why is it better to initialize a string object with the statement, String str = "India" as against String str = new String ("India")

Well, apparently, String is implemented in Java using a String pool. Now, what happens here is that once you create an object using the statement, str = "India" and subsequently reassign str with the statement, str = "China"; the former object "India" on the heap loses its reference but is not immediately garbage collected. If you then had to create another string with the former value "India", the already created object is reused. This obviates the need to recreate already existent objects. This is in fact one of the reasons why immutable objects do not provide the clone() or copy constructor method.

Now, let's say you initialize a string using the statement,
String str = new String ("India"). The above idea of deferred garbage collection applies here as well. But if you happened to write another String str2 = new String ("India"), Java would in fact create yet another object with value, "India" on the heap. This is to say that the existing String object would not be reused with a duplicate reference. This may be visualized as shown below:



Such duplicate object creation may not be in keeping with the space efficiency of the program as evidenced by the above example. A simple way to check the above result would be to compare str with str2: str == str2 which would return false. The object hash codes would also be different as they are two different objects. It must be noted that str.equals(str2) would return true.

Just another subtle addition to the above note. This scheme of deferred garbage collection applies only with some object types, String being one of them. For those to which it does not apply, (Integer, for example), the two initialization statements are in fact, equivalent.



No comments:

Post a Comment