{"id":1153,"date":"2012-05-26T23:26:22","date_gmt":"2012-05-26T21:26:22","guid":{"rendered":"http:\/\/doanduyhai.wordpress.com\/?p=1153"},"modified":"2012-05-26T23:26:22","modified_gmt":"2012-05-26T21:26:22","slug":"object-immutability-in-java","status":"publish","type":"post","link":"https:\/\/www.doanduyhai.com\/blog\/?p=1153","title":{"rendered":"Object immutability in Java"},"content":{"rendered":"<p>I&#8217;ve seen many developers struggling with subtle mutability issues in Java. This article will expose the major gotchas of object immutability.<\/p>\n<p><!--more--><\/p>\n<h1>I Definition<\/h1>\n<p> An object is said to be &#8220;<strong>immutable<\/strong>&#8221; when, <strong>after its initialization (object creation), its internal state does not change<\/strong>.<\/p>\n<p> The definition looks quite simple and straightforward but the &#8220;its internal state does not change&#8221; part is very hard to obtain.<\/p>\n<p> One simple example of immutable object in Java is the String class. One created, the text content of a String instance can never change. Everytime you call a helper method on this String instance (<em>concat(), subString(), toLowerCase()&#8230;<\/em>), a new instance of String is returned, the original String instance remains unchanged.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\nString myString =&amp;quot;TEST&amp;quot;;\n\nString subString = myString.toLowerCase();\n\nSystem.out.println(&amp;quot;myString == subString ? &amp;quot;+ (myString == subString));\n\n<\/pre>\n<p>The above code will display as output:<\/p>\n<pre>myString == subString ? false<\/pre>\n<p>&nbsp;<\/p>\n<h1>II Immutability and encapsulation<\/h1>\n<p> The first idea to make an object immutable is to declare all its attributes &#8220;<strong>private<\/strong>&#8221; and to remove all <strong>setters<\/strong>. But without setters we have to find a way to initialize these private attributes. One solution could be declaring them as constructor arguments. During the object initialization, we provide all the attributes. After the initialization, since the attribute are privates they cannot be accessed from the outside, thus guaranting immutabitily.<\/p>\n<p> Below an example:<\/p>\n<pre class=\"brush: java; highlight: [3,5]; title: ; notranslate\" title=\"\">\npublic class ImmutableByEncapsulation\n{\n\tprivate List&amp;lt;String&amp;gt; items;\n\n\tpublic ImmutableByEncapsulation(List&amp;lt;String&amp;gt; items) {\n\t\tthis.items = items;\n\t}\n\n\t@SuppressWarnings(&amp;quot;unused&amp;quot;)\n\tprivate ImmutableByEncapsulation() {\n\t\tsuper();\n\t}\n\n\tpublic String getItemByPosition(int position)\n\t{\n\t\tif (position &amp;gt;= 0 &amp;amp;&amp;amp; position &amp;lt; this.items.size())\n\t\t{\n\t\t\treturn this.items.get(position);\n\t\t}\n\n\t\treturn null;\n\t}\n}\n<\/pre>\n<p> The above code shows an <strong>ImmutableByEncapsulation<\/strong> class with a constructor accepting a List of String (<em>default constructor is made private to force initialization with List of String<\/em>).<\/p>\n<p> Once created, the internal items list cannot be accessed from the outside so cannot be modified.<\/p>\n<p> Indeed there is a big <strong>flaw<\/strong> in this example. Let&#8217;s check the below code:<\/p>\n<pre class=\"brush: java; highlight: [13]; title: ; notranslate\" title=\"\">\n\nList&amp;lt;String&amp;gt; items = new ArrayList&amp;lt;String&amp;gt;();\n\nitems.add(&amp;quot;table&amp;quot;);\nitems.add(&amp;quot;chair&amp;quot;);\nitems.add(&amp;quot;desk&amp;quot;);\n\nImmutableByEncapsulation ob = new ImmutableByEncapsulation(items);\n\n...\nob.getItemByPosition(2);\n...\n\nitems.add(&amp;quot;sofa&amp;quot;); \/\/ Immutability broken !!!\n...\n<\/pre>\n<p> The previous design is completely broken because the main code still have a reference to the <em>items<\/em> list passed as constructor argument. The internal <em>items<\/em> list can be modified outside of <strong>ImmutableByEncapsulation<\/strong>.<\/p>\n<p>To fix this, we need to make a copy of the <em>items<\/em> list passed as constructor argument.<\/p>\n<pre class=\"brush: java; highlight: [3,6]; title: ; notranslate\" title=\"\">\npublic class ImmutableByEncapsulation\n{\n\tprivate List&amp;lt;String&amp;gt; items;\n\n\tpublic ImmutableByEncapsulation(List&amp;lt;String&amp;gt; items) {\n\t\tthis.items = new ArrayList&amp;lt;String&amp;gt;(items);\n\t}\n\t...\n}\t\n<\/pre>\n<p>This way, any modification made to the <em>items<\/em> list after <strong>ImmutableByEncapsulation<\/strong> initialization will not impact its internal state.<\/p>\n<p>&nbsp;<\/p>\n<h1>III Immutability and object graph<\/h1>\n<p>The above solution makes the <strong>ImmutableByEncapsulation<\/strong> immutable because the list of <em>items<\/em> is of type String, which is immutable. Had we changed it to another <strong>non-immutable<\/strong> type, it wouldn&#8217;t work.<\/p>\n<p> Let&#8217;s turn the list of String into a list of <strong>Furniture<\/strong>, a custom type:<\/p>\n<pre class=\"brush: java; highlight: [49]; title: ; notranslate\" title=\"\">\npublic class Furniture\n{\n\tprivate String type;\n\tprivate int quantity;\n\n\tpublic Furniture(String type, int quantity) {\n\t\tsuper();\n\t\tthis.type = type;\n\t\tthis.quantity = quantity;\n\t}\n\n\tpublic String getType() {return type;}\n\n\tpublic void setType(String type) {this.type = type;}\n\n\tpublic int getQuantity() {return quantity;}\n\n\tpublic void setQuantity(int quantity) {\tthis.quantity = quantity;}\t\n}\n\npublic class ImmutableByEncapsulation\n{\n\tprivate List&amp;lt;Furniture&amp;gt; items;\n\n\tpublic ImmutableByEncapsulation(List&amp;lt;Furniture&amp;gt; items) {\n\t\tthis.items = new ArrayList&amp;lt;Furniture&amp;gt;(items);\n\t}\n\t...\t\n}\n\n...\n...\nList&amp;lt;Furniture&amp;gt; items = new ArrayList&amp;lt;Furniture&amp;gt;();\n\nFurniture table = new Furniture(&amp;quot;table&amp;quot;,2);\nFurniture chair = new Furniture(&amp;quot;chair&amp;quot;,10);\nFurniture sofa = new Furniture(&amp;quot;sofa&amp;quot;,1);\n\nitems.add(table);\nitems.add(chair);\nitems.add(sofa);\n\nImmutableByEncapsulation ob = new ImmutableByEncapsulation(items);\n\n...\nob.getItemByPosition(2);\n...\n\nchair.setQuantity(100) \/\/ Immutability broken !!\n...\n<\/pre>\n<p> This is the immutability cascade issue. To make an object really immutable, all its internal object graph should be immutable.<\/p>\n<p> Please note that it was easy to make our <strong>Furniture<\/strong> class immutable. All we need to do is to remove the setter methods. Since the String and primitive types are immutable, the class would be immutable after its initialization.<br \/>\n&nbsp;<\/p>\n<h1>IV Immutability and cloning<\/h1>\n<p> For real life use cases it is sometimes required that the immutable object exposes its internal state as read-only value. In this case, two possible solutions:<\/p>\n<ul>\n<li><strong>method returned values are immutable object<\/strong>. This implies that the internal state of the object is composed of immutable components as well<\/li>\n<li><strong>method returned values are a clones of an internal components<\/strong>. In this case the returned clone can be modified outside of the object without breaking immutability contract<\/li>\n<\/ul>\n<p>Let&#8217;s see an example.<\/p>\n<pre class=\"brush: java; highlight: [49]; title: ; notranslate\" title=\"\">\npublic class ImmutableByCloning\n{\n\tprivate List&amp;lt;MutableObject&amp;gt; items;\n\n\tpublic ImmutableByCloning(List&amp;lt;MutableObject&amp;gt; items) {\n\t\tthis.items = new ArrayList&amp;lt;MutableObject&amp;gt;();\n\t\tfor (MutableObject mutableItem : items)\n\t\t{\n\t\t\tthis.items.add(mutableItem.clone());\n\t\t}\n\t}\n\n\t@SuppressWarnings(&amp;quot;unused&amp;quot;)\n\tprivate ImmutableByCloning() {}\n\n\tpublic List&amp;lt;MutableObject&amp;gt; getItems()\n\t{\n\n\t\tList&amp;lt;MutableObject&amp;gt; returnedItems = new ArrayList&amp;lt;MutableObject&amp;gt;();\n\t\tfor (MutableObject mutableItem : this.items)\n\t\t{\n\t\t\treturnedItems.add(mutableItem.clone());\n\t\t}\n\n\t\treturn returnedItems;\n\t}\n}\n<\/pre>\n<p>In the above code, we can see that there is a double level of cloning. <\/p>\n<p>First in the constructor, a new list is created in which we put all the clones of MutableObject. The list is cloned (<strong>new ArrayList<\/strong>) and each element inside the list is also cloned. <\/p>\n<p> This pattern ensures that no reference of the internal state (reference on <em>items<\/em> attribute or on each <strong>MutableObject<\/strong> in the <em>items<\/em> list) leaks outside of the class.<\/p>\n<p> The same pattern is applied to the getter <em>getItems()<\/em> for immutability.<br \/>\n&nbsp;<\/p>\n<h1>V Protect your immutables !<\/h1>\n<p> Even if you have spent hours designing a perfectly immutable class (by implementing <em>clone()<\/em> for all the internal components). There is still one possibility to ruin your hard work. <\/p>\n<p> How ? <\/p>\n<p> <strong>Simply by extending your class and re-defining the safe getters and removing object cloning pattern!<\/strong><\/p>\n<p> To really enforce strict immutability, you need to declare your class as <strong>final<\/strong> so it cannot be extended.<\/p>\n<p>&nbsp;<\/p>\n<h1>VI Conclusion<\/h1>\n<p> <strong>After these few examples, we can see that any time a reference to an internal component is accessible from outside of the object (<em>constructor argument, getters or simple method returned values<\/em>) there is a risk of modification and the immutability can be broken, unless the return values are themselves immutable.<\/strong><\/p>\n<p>From this observation, some rules of thumb can be drawn. To make an object immutable<\/p>\n<ul>\n<li>either all of its internal components shoud be immutable<\/li>\n<li>or cloning should be applied to all constructor arguments and method returned values. This implies that all the internal components redefine the clone() method properly<\/li>\n<\/ul>\n<p> Neither of the above conditions is simple. Making a class truly immutable is hard, making the internal component graph immutable is even harder. The cloning solution is not a piece of cake either. Redefining the <em>clone()<\/em> method in a proper manner to implement <strong>deep copy<\/strong> is a dawnting task, especially when you have a complex object graph.<\/p>\n<p> There are some articles over there on the Web with object serialization as a solution for object deep copy but<strong> the impact on performance is huge<\/strong>. Object serialization can be sometimes hundred times slower than manual <em>clone()<\/em> redefinition.<\/p>\n<p> At the bottom line, object immutability is a quite complex subject. Immutability in a &#8220;classical&#8221; Java application is usually not really an issue.<\/p>\n<p> Immutability becomes useful and interesting when dealing with multi-threaded applications because immutable objects are by nature <strong>thread-safe<\/strong> and save from synchronization headache.<\/p>\n<p>&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve seen many developers struggling with subtle mutability issues in Java. This article will expose the major gotchas of object immutability.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[22,6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1153"}],"collection":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1153"}],"version-history":[{"count":0,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1153\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.doanduyhai.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}