{"id":194,"date":"2021-01-19T22:30:48","date_gmt":"2021-01-19T22:30:48","guid":{"rendered":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/?page_id=194"},"modified":"2021-02-05T17:04:17","modified_gmt":"2021-02-05T17:04:17","slug":"serialization","status":"publish","type":"page","link":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/","title":{"rendered":"Serialization"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a6d49655e1f4\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a6d49655e1f4\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Object_Streams_Serialization\" >Object Streams &amp; Serialization<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Classes_ObjectOutputStream_and_ObjectInputStream\" >Classes ObjectOutputStream and ObjectInputStream<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Serializing_Families_of_Classes\" >Serializing Families of Classes<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Serialization_Class_Versioning\" >Serialization &amp; Class Versioning<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#A_Simple_Application\" >A Simple Application<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Changing_a_Class\" >Changing a Class<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Specifying_an_Explicit_Version\" >Specifying an Explicit Version<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Custom_Serialization_Security\" >Custom Serialization &amp; Security<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Preventing_Serialization\" >Preventing Serialization<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Custom_Serialization\" >Custom Serialization<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Adding_Items_to_the_Serialized_Class\" >Adding Items to the Serialized Class<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#Advanced_Serialization\" >Advanced Serialization<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#The_Externalizable_Interface\" >The&nbsp;Externalizable&nbsp;Interface<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/course-topics\/serialization\/#The_ObjectInputValidation_Interface\" >The&nbsp;ObjectInputValidation&nbsp;Interface<\/a><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n<p class=\"wp-block-paragraph\">One disadvantage of storing objects in memory, during program execution, is that those objects only exist until the program terminates, at which point their contents are lost. Wouldn&#8217;t it be nice if somehow the state of interesting objects could be saved and later restored, so that the program could maintain its state over multiple program invocations? Or even to convey the state of those objects to another program &#8212; even on another machine?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Well, you can. This is called&nbsp;<em>Object Persistence<\/em>, and it&#8217;s achieved in Java through a process called&nbsp;<em>serialization<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Object_Streams_Serialization\"><\/span>Object Streams &amp; Serialization<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the relevant class hierarchy for object streams:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">(Package&nbsp;<code><strong>java.io<\/strong><\/code>)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Object<strong>\n    InputStream\n        ObjectInputStream\n    OutputStream\n        ObjectOutputStream<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Serializable\n    Externalizable<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>ObjectInputValidation<\/strong><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Classes_ObjectOutputStream_and_ObjectInputStream\"><\/span>Classes <strong>ObjectOutputStream<\/strong> and <strong>ObjectInputStream<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Serialization is achieved using the classes <strong>ObjectOutputStream<\/strong> and <strong>ObjectInputStream<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, a class must implement the&nbsp;<strong>Serializable<\/strong>&nbsp;interface to be successfully serialized. (This is not the default for security reasons.) The&nbsp;<strong>Serializable<\/strong>&nbsp;interface is a &#8216;marker interface&#8217; &#8212; that is, it has no methods &#8212; so no other changes need to be made to your classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To serialize your class&nbsp;<em>out<\/em>&nbsp;to an&nbsp;<strong>ObjectOutputStream<\/strong>, you call that stream&#8217;s&nbsp;<strong>writeObject()<\/strong>&nbsp;method. Conversely, when you wish to serialize&nbsp;<em>in<\/em>&nbsp;from an&nbsp;<strong>ObjectInputStream<\/strong>, you call that stream&#8217;s <strong>readObject()<\/strong> method.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is how you can serialize out to a file. First, let&#8217;s create some classes to serialize:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\n\npublic class Person\n    implements Serializable\n{\n    public Person(String name, int age)\n    {\n        m_name = name;\n        m_age  = age;\n    }\n    \n    public String getName()\n    {\n        return m_name;\n    }\n    \n    public int getAge()\n    {\n        return m_age;\n    }\n    \n    public String toString()\n    {\n        String s = getClass().getName();\n        s += &quot;:Name=&quot; + m_name + &quot;, Age=&quot; + m_age;\n        return s;\n    }\n    \n    \/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\n    private String  m_name;\n    private int     m_age;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\npublic class Employee\n    extends Person\n{\n    public Employee(String name,   int  age, \n                    double salary, long id)\n    {\n        super(name, age);\n        m_salary = salary;\n        m_id = id;\n    }\n    \n    public double getSalary()\n    {\n        return m_salary;\n    }\n    \n    public long getId()\n    {\n        return m_id;\n    }\n    \n    public String toString()\n    {\n        String s = super.toString();\n        s += &quot;, Salary=&quot; + m_salary + &quot;, ID=&quot; + m_id;\n        return s;\n    }\n    \n    \n    \/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\n    private double m_salary;\n    private long   m_id;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.util.Vector;\n\npublic class Manager\n    extends Employee\n{\n    public Manager(String name,   int  age,\n                   double salary, long id)\n    {\n        super(name, age, salary, id);\n    }\n    \n    public void addEmployee(Employee emp)\n    {\n        m_directReports.addElement(emp);\n    }\n\n    public void removeEmployee(Employee emp)\n    {\n        m_directReports.removeElement(emp);\n    }\n    \n    \/\/\/\/\/ Data \/\/\/\/\n    private Vector m_directReports = new Vector();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how you serialize objects of these types out to a file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\n\npublic class SimpleSerializeOut\n{\n    public static void main(String&#x5B;] args)\n    {\n        Manager bill = new Manager(&quot;Bill Gates&quot;, 47,\n                                   100000000000.00, 1);\n        Employee bob = new Employee(&quot;Bob Dole&quot;, 69,\n                                    100000.00, 345);\n        ObjectOutputStream out = null;\n        try\n        {\n            out = new ObjectOutputStream(\n                          new FileOutputStream(\n                                   &quot;employees.dat&quot;));\n            out.writeObject(bob);\n            out.writeObject(bill);\n            System.out.println(&quot;Serialization successful.&quot;);\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n            System.out.println(&quot;Serialization failed.&quot;);\n        }\n        finally\n        {\n            if (out != null)\n            {\n                try\n                {\n                    out.close();\n                }\n                catch(IOException e)\n                {}\n            }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">And here&#8217;s how you serialize them back in again, from the file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\n\npublic class SimpleSerializeIn\n{\n    public static void main(String&#x5B;] args)\n    {\n        Employee emp;\n        Manager  mgr;\n        \n        ObjectInputStream in = null;\n        boolean failed = true;\n        try\n        {\n            in = new ObjectInputStream(\n                          new FileInputStream(\n                                   &quot;employees.dat&quot;));\n            emp = (Employee)in.readObject();\n            System.out.println(&quot;emp: &quot; + emp);\n            mgr = (Manager)in.readObject();\n            System.out.println(&quot;mgr: &quot; + mgr);\n            System.out.println(&quot;Serialization successful.&quot;);\n            failed = false;\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        catch(ClassNotFoundException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (in != null)\n            {\n                try\n                {\n                    in.close();\n                }\n                catch(IOException e)\n                {}\n            }\n            if (failed)\n                System.err.println(&quot;Serialization failed.&quot;);\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This latter program outputs the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>emp: serialization.Employee:Name=Bob Dole, Age=69, Salary=100000.0, ID=345\nmgr: serialization.Manager:Name=Bill Gates, Age=47, Salary=1.0E11, ID=1\nSerialization successful.<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">which shows that it worked!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Serializing_Families_of_Classes\"><\/span>Serializing Families of Classes<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A number of issues arise when you attempt to serialize a related set of class instances:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>All of the classes must be marked as&nbsp;<strong>Serializable<\/strong><\/li><li>If the same object is referenced from more than one place, that object should still be serialized only once<\/li><li>There should be no situation where unlimited recursion occurs<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The really nice thing about serialization is that the second and third items are taken care of automatically.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s take our previous example of simple serialization, and modify the classes somewhat, to emphasize what happens when there are multiple references to the same object:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [24,25,26,27,28,29,30,31,32,33,34,35]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\n\npublic class Person\n    implements Serializable\n{\n    public Person(String name, int age)\n    {\n        m_name = name;\n        m_age  = age;\n    }\n    \n    public String getName()\n    {\n        return m_name;\n    }\n    \n    public int getAge()\n    {\n        return m_age;\n    }\n    \n    public String toString()\n    {\n        String s = getClass().getName();\n        \/\/ Strip off package name\n        int index = s.lastIndexOf(&#039;.&#039;);\n        if (index != -1)\n            s = s.substring(index+1, s.length());\n            \n        s += &quot;:Hashcode=@&quot; + Integer.toHexString(hashCode()) + \n             &quot;, Name=&quot; + m_name + &quot;, Age=&quot; + m_age;\n        return s;\n    }\n    \n    \/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\n    private String  m_name;\n    private int     m_age;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [18,19,20,21,22,23,24,25,26,37]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\npublic class Employee\n    extends Person\n{\n    public Employee(String name, int  age, \n                    double salary)\n    {\n        super(name, age);\n        m_salary = salary;\n    }\n    \n    public double getSalary()\n    {\n        return m_salary;\n    }\n    \n    public void setManager(Manager mgr)\n    {\n        m_manager = mgr;\n    }\n    \n    public Manager getManager()\n    {\n        return m_manager;\n    }\n    \n    public String toString()\n    {\n        String s = super.toString();\n        s += &quot;, Salary=&quot; + m_salary;\n        return s;\n    }\n    \n    \/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\n    private double  m_salary;\n    private Manager m_manager;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,54]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.util.Enumeration;\nimport java.util.Vector;\n\npublic class Manager\n    extends Employee\n{\n    public Manager(String name, int  age,\n                   double salary)\n    {\n        super(name, age, salary);\n    }\n    \n    public void setSecretary(Employee sec)\n    {\n        m_secretary = sec;\n    }\n    \n    public Employee getSecretary()\n    {\n        return m_secretary;\n    }\n    \n    public void addDirectReport(Employee emp)\n    {\n        m_directReports.addElement(emp);\n    }\n\n    public void removeDirectReport(Employee emp)\n    {\n        m_directReports.removeElement(emp);\n    }\n    \n    public int getDirectReportsCount()\n    {\n        return m_directReports.size();\n    }\n    \n    public Enumeration getDirectReports()\n    {\n        return m_directReports.elements();\n    }\n    \n    public String toString()\n    {\n        String s = super.toString();\n        s += &quot;, Secretary=&#x5B;&quot; + m_secretary + &quot;]&quot;;\n        return s;\n    }\n    \n    \/\/\/\/\/ Data \/\/\/\/\n    private Vector   m_directReports = new Vector();\n    private Employee m_secretary;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">And a new <strong>Organization<\/strong> class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\nimport java.util.Enumeration;\nimport java.util.Vector;\n\npublic class Organization\n    implements Serializable\n{\n    public Organization(String name)\n    {\n        m_name = name;\n    }\n    \n    public String getName()\n    {\n        return m_name;\n    }\n    \n    public void setPresident(Manager pres)\n    {\n        m_president = pres;\n    }\n    \n    public Manager getPresident()\n    {\n        return m_president;\n    }\n    \n    public void addEmployee(Employee emp)\n    {\n        m_employees.addElement(emp);\n    }\n\n    public void removeEmployee(Employee emp)\n    {\n        m_employees.removeElement(emp);\n    }\n    \n    public int getEmployeeCount()\n    {\n        return m_employees.size();\n    }\n    \n    public Enumeration getEmployees()\n    {\n        return m_employees.elements();\n    }\n    \n    public String toString()\n    {\n        String s = getName() + &quot; has &quot; +\n                   getEmployeeCount() + &quot; employees:\\n&quot;;\n        \/\/Create organization chart, starting at president\n        s += toString(m_president, 0);\n        return s;\n    }\n    \n    private static String toString(Employee emp, \n                                   int indentLevel)\n    {\n        String indent = &quot;&quot;;\n        for (int i = 0; i &lt; indentLevel; i++)\n            indent += &quot;  &quot;;\n        String s = indent;\n        s += emp.toString() + &quot;\\n&quot;;\n        if (emp instanceof Manager)\n        {\n            Manager mgr = (Manager)emp;\n            Enumeration en = mgr.getDirectReports();\n            while (en.hasMoreElements())\n            {\n                Employee e = (Employee)en.nextElement();\n                s += toString(e, indentLevel + 1);\n            }\n        }\n        return s;\n    }\n    \n    \/\/\/\/ Data \/\/\/\/\n    private String  m_name;\n    private Manager m_president;\n    private Vector  m_employees = new Vector();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">I modified the classes to add a reference for each&nbsp;<strong>Employee<\/strong>&#8216;s&nbsp;<strong>Manager<\/strong>, and each&nbsp;<strong>Manager<\/strong>&#8216;s secretary. I augmented the&nbsp;<strong>Person<\/strong>&nbsp;class&#8217;s&nbsp;<strong>toString()<\/strong>&nbsp;method to show more specifics about the object (including its hashcode), and I removed the&nbsp;<strong>m_id<\/strong>&nbsp;field from&nbsp;<strong>Employee<\/strong>&nbsp;to simplify the output. Finally, I added a new class,&nbsp;<strong>Organization<\/strong>, which has references to each of its&nbsp;<strong>Employee<\/strong>s, and contains a&nbsp;<strong>toString()<\/strong>&nbsp;method which is capable of returning an &#8220;org chart&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the modified program to serialize out the family of related objects:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [12,13,14,15,16,17,18,19,20,21,22,23,31,32,33,34,35,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\nimport java.util.Enumeration;\n\npublic class FamilySerializeOut\n{\n    public static void main(String&#x5B;] args)\n    {\n        Organization org = createOrganization();\n        System.out.println(&quot;Org Chart:\\n&quot; + org);\n        \n        \/\/ Make asarray of all the organization&#039;s employees...\n        Employee&#x5B;] emps = new Employee&#x5B;org.getEmployeeCount()];\n        System.out.println(&quot;emps:&quot;);\n        Enumeration en = org.getEmployees();\n        for (int emp = 0; en.hasMoreElements(); emp++)\n        {\n            emps&#x5B;emp] = (Employee)en.nextElement();\n            System.out.println(&quot;&#x5B;&quot; + emp + &quot;]:&quot; + emps&#x5B;emp]);\n        }\n        \n        ObjectOutputStream out = null;\n        boolean failed = true;\n        try\n        {\n            out = new ObjectOutputStream(\n                          new FileOutputStream(\n                                   &quot;org.dat&quot;));\n            \/\/ Serialize out the organization\n            out.writeObject(org);\n            \/\/ Serialize out the array of employees\n            out.writeObject(emps);\n            \n            failed = false;\n            System.out.println(&quot;Serialization successful.&quot;);\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (out != null)\n            {\n                try\n                {\n                    out.close();\n                }\n                catch(IOException e)\n                {}\n            }\n            if (failed)\n                System.out.println(&quot;Serialization failed.&quot;);\n        }\n    }\n    \n    private static Organization createOrganization()\n    {\n        Organization org = new Organization(&quot;Microsquish&quot;);\n        Manager billg = createManager(org, null, null,\n                                      &quot;Bill Gates&quot;, 47,\n                                      100000000000.00);\n        org.setPresident(billg);\n        \n        Employee bettyb = createEmployee(org, billg,\n                                         &quot;Betty Boop&quot;, 56,\n                                         36000.00);\n        billg.setSecretary(bettyb);\n        \n        createSalesOrg(org);\n        createEngineeringOrg(org, bettyb);\n        \n        return org;\n    }\n    \n    private static Manager createSalesOrg(Organization org)\n    {\n        Manager elvisp = createManager(\n                                    org, \n                                    org.getPresident(), \n                                    null,\n                                    &quot;Elvis Presley&quot;, 57,\n                                    2000000.00);\n        Employee oliveo = createEmployee(\n                                    org, elvisp,\n                                    &quot;Olive Oyl&quot;, 48,\n                                    32000.00);\n        elvisp.setSecretary(oliveo);\n        \n        createEmployee(org, elvisp, \n                       &quot;Prince&quot;, 25, 200000.00);\n        createEmployee(org, elvisp,\n                       &quot;Madonna&quot;, 36, 400000.00);\n        \n        return elvisp;\n    }\n    \n    private static Manager createEngineeringOrg(\n                                    Organization org,\n                                    Employee sec)\n    {\n        Manager carlp = createManager(\n                                    org, \n                                    org.getPresident(), \n                                    sec,\n                                    &quot;Carl Perkins&quot;, 59,\n                                    2000000.00);       \n        createEmployee(org, carlp, \n                       &quot;Porky Pig&quot;, 42, 20000.00);\n        createEmployee(org, carlp,\n                       &quot;Taz Devil&quot;, 40, 40000.00);\n        \n        return carlp;\n    }\n    \n    private static Manager createManager(\n                                    Organization org, \n                                    Manager boss,\n                                    Employee sec,\n                                    String name, int age,\n                                    double salary)\n    {\n        Manager mgr = new Manager(name, age, salary);\n        doHousekeeping(mgr, org, boss);\n        if (sec != null)\n            mgr.setSecretary(sec);\n        \n        return mgr;\n    }\n    \n    private static Employee createEmployee(\n                                    Organization org,\n                                    Manager boss,\n                                    String name, int age,\n                                    double salary)\n    {\n        Employee emp = new Employee(name, age, salary);\n        doHousekeeping(emp, org, boss);\n        return emp;\n    }\n    \n    private static void doHousekeeping(\n                                Employee emp,\n                                Organization org, \n                                Manager boss)\n    {\n        org.addEmployee(emp);\n        if (boss != null)\n        {\n            boss.addDirectReport(emp);\n            emp.setManager(boss);\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which adds a number of methods to create an&nbsp;<strong>Organization<\/strong>, and populate it with&nbsp;<strong>Employee<\/strong>s and&nbsp;<strong>Manager<\/strong>s and secretaries, and uses the <strong>Organization<\/strong>&#8216;s toString() method to print out the entire &#8220;org chart&#8221;. Then, to show that the handling of multiple references works across calls to <strong>writeObject()<\/strong>, it creates an array of&nbsp;<strong>Employee<\/strong>s and populates it with references to all the organization&#8217;s employees. In the process, it prints out the contents of the array. Finally, it serializes out the organization and then the array of employees.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what it outputs on my machine&nbsp;<em>(note the hashcode values &#8212; each one identifies a unique object)<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Org Chart:\nMicrosquish has 9 employees:\nManager:Hashcode=@277e69, Name=Bill Gates, Age=47, Salary=1.0E11, Secretary=&#91;Employee:Hashcode=@277e64, Name=Betty Boop, Age=56, Salary=36000.0]\n  Employee:Hashcode=@277e64, Name=Betty Boop, Age=56, Salary=36000.0\n  Manager:Hashcode=@277e61, Name=Elvis Presley, Age=57, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@277e5c, Name=Olive Oyl, Age=48, Salary=32000.0]\n    Employee:Hashcode=@277e5c, Name=Olive Oyl, Age=48, Salary=32000.0\n    Employee:Hashcode=@277e59, Name=Prince, Age=25, Salary=200000.0\n    Employee:Hashcode=@277e56, Name=Madonna, Age=36, Salary=400000.0\n  Manager:Hashcode=@277e53, Name=Carl Perkins, Age=59, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@277e64, Name=Betty Boop, Age=56, Salary=36000.0]\n    Employee:Hashcode=@277e4e, Name=Porky Pig, Age=42, Salary=20000.0\n    Employee:Hashcode=@277e4b, Name=Taz Devil, Age=40, Salary=40000.0\n\nemps:\n&#91;0]:Manager:Hashcode=@277e69, Name=Bill Gates, Age=47, Salary=1.0E11, Secretary=&#91;Employee:Hashcode=@277e64, Name=Betty Boop, Age=56, Salary=36000.0]\n&#91;1]:Employee:Hashcode=@277e64, Name=Betty Boop, Age=56, Salary=36000.0\n&#91;2]:Manager:Hashcode=@277e61, Name=Elvis Presley, Age=57, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@277e5c, Name=Olive Oyl, Age=48, Salary=32000.0]\n&#91;3]:Employee:Hashcode=@277e5c, Name=Olive Oyl, Age=48, Salary=32000.0\n&#91;4]:Employee:Hashcode=@277e59, Name=Prince, Age=25, Salary=200000.0\n&#91;5]:Employee:Hashcode=@277e56, Name=Madonna, Age=36, Salary=400000.0\n&#91;6]:Manager:Hashcode=@277e53, Name=Carl Perkins, Age=59, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@277e64, Name=Betty Boop, Age=56, Salary=36000.0]\n&#91;7]:Employee:Hashcode=@277e4e, Name=Porky Pig, Age=42, Salary=20000.0\n&#91;8]:Employee:Hashcode=@277e4b, Name=Taz Devil, Age=40, Salary=40000.0\nSerialization successful.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let&#8217;s serialize the results back in from the file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [17,18,19,20,21,22,23]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\n\npublic class FamilySerializeIn\n{\n    public static void main(String&#x5B;] args)\n    {\n        ObjectInputStream in = null;\n        boolean failed = true;\n        try\n        {\n            in = new ObjectInputStream(\n                          new FileInputStream(\n                                   &quot;org.dat&quot;));\n            Organization org = (Organization)in.readObject();\n            System.out.println(&quot;Org Chart:\\n&quot; + org);\n            Employee&#x5B;] emps = (Employee&#x5B;])in.readObject();\n            System.out.println(&quot;emps:&quot;);\n            for (int emp = 0; emp &lt; emps.length; emp++)\n                System.out.println(&quot;&#x5B;&quot; + emp + &quot;]:&quot; + emps&#x5B;emp]);\n            System.out.println(&quot;Serialization successful.&quot;);\n            failed = false;\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        catch(ClassNotFoundException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (in != null)\n            {\n                try\n                {\n                    in.close();\n                }\n                catch(IOException e)\n                {}\n            }\n            if (failed)\n                System.err.println(&quot;Serialization failed.&quot;);\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Note how little had to be changed!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This outputs, on my machine&nbsp;<em>(again, note the hashcode values):<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Org Chart:\nMicrosquish has 9 employees:\nManager:Hashcode=@27812d, Name=Bill Gates, Age=47, Salary=1.0E11, Secretary=&#91;Employee:Hashcode=@278127, Name=Betty Boop, Age=56, Salary=36000.0]\n  Employee:Hashcode=@278127, Name=Betty Boop, Age=56, Salary=36000.0\n  Manager:Hashcode=@278123, Name=Elvis Presley, Age=57, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@27811d, Name=Olive Oyl, Age=48, Salary=32000.0]\n    Employee:Hashcode=@27811d, Name=Olive Oyl, Age=48, Salary=32000.0\n    Employee:Hashcode=@278119, Name=Prince, Age=25, Salary=200000.0\n    Employee:Hashcode=@278115, Name=Madonna, Age=36, Salary=400000.0\n  Manager:Hashcode=@278111, Name=Carl Perkins, Age=59, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@278127, Name=Betty Boop, Age=56, Salary=36000.0]\n    Employee:Hashcode=@27810b, Name=Porky Pig, Age=42, Salary=20000.0\n    Employee:Hashcode=@278107, Name=Taz Devil, Age=40, Salary=40000.0\n\nemps:\n&#91;0]:Manager:Hashcode=@27812d, Name=Bill Gates, Age=47, Salary=1.0E11, Secretary=&#91;Employee:Hashcode=@278127, Name=Betty Boop, Age=56, Salary=36000.0]\n&#91;1]:Employee:Hashcode=@278127, Name=Betty Boop, Age=56, Salary=36000.0\n&#91;2]:Manager:Hashcode=@278123, Name=Elvis Presley, Age=57, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@27811d, Name=Olive Oyl, Age=48, Salary=32000.0]\n&#91;3]:Employee:Hashcode=@27811d, Name=Olive Oyl, Age=48, Salary=32000.0\n&#91;4]:Employee:Hashcode=@278119, Name=Prince, Age=25, Salary=200000.0\n&#91;5]:Employee:Hashcode=@278115, Name=Madonna, Age=36, Salary=400000.0\n&#91;6]:Manager:Hashcode=@278111, Name=Carl Perkins, Age=59, Salary=2000000.0, Secretary=&#91;Employee:Hashcode=@278127, Name=Betty Boop, Age=56, Salary=36000.0]\n&#91;7]:Employee:Hashcode=@27810b, Name=Porky Pig, Age=42, Salary=20000.0\n&#91;8]:Employee:Hashcode=@278107, Name=Taz Devil, Age=40, Salary=40000.0\nSerialization successful.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This shows that each unique object was serialized out once, and then serialized back in only once.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Serialization_Class_Versioning\"><\/span>Serialization &amp; Class Versioning<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When we serialize data, we must be careful about making changes to the classes and expecting the serialization to continue working.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here, we explain the problem and then show how it&#8217;s addressed.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Simple_Application\"><\/span>A Simple Application<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Consider the following classes:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\n\npublic class Address implements Serializable\n{\n    public Address(String name, String address)\n    {\n        m_name = name;\n        m_address = address;\n    }\n    \n    public String getName()\n    {\n        return m_name;\n    }\n    \n    public String getAddress()\n    {\n        return m_address;\n    }\n    \n    \/\/\/\/\/ Private data \/\/\/\/\/\n    private String m_name;\n    private String m_address;\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\nimport java.util.Enumeration;\nimport java.util.Hashtable;\n\npublic class AddressBook implements Serializable\n{\n    public Address lookup(String name)\n    {\n        return (Address) m_table.get(name);\n    }\n    \n    public Address add(String name, String address)\n    {\n        return (Address) m_table.put(name,\n                                     new Address(name,\n                                                 address));\n    }\n    \n    public int size()\n    {\n        return m_table.size();\n    }\n    \n    public Enumeration addresses()\n    {\n        return m_table.elements();\n    }\n    \n    \/\/\/\/ Private data \/\/\/\/\n    private Hashtable m_table = new Hashtable();\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now, let&#8217;s write a program to populate an&nbsp;<strong>AddressBook<\/strong>&nbsp;with&nbsp;<strong>Address<\/strong>es and then serialize the results out:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\n\npublic class SerializeOutAddressBook\n{\n    public static void main(String&#x5B;] args)\n    {\n        AddressBook book = new AddressBook();\n        book.add(&quot;Bill Gates&quot;, &quot;1000 High-on-the-Hog Drive&quot;);\n        book.add(&quot;Scott McNealy&quot;, &quot;4000 Java Circle&quot;);\n        book.add(&quot;Linus Torvalds&quot;, &quot;300 Linux Lane&quot;);\n        \n        FileOutputStream fout = null;\n        ObjectOutputStream out = null;\n        try\n        {\n            fout = new FileOutputStream(&quot;addrbook.ser&quot;);\n            out = new ObjectOutputStream(fout);\n            out.writeObject(book);\n            \n            System.out.println(&quot;Serialization successful!&quot;);\n        }\n        catch(IOException ex)\n        {\n            ex.printStackTrace();\n        }\n        finally\n        {\n            try\n            {\n                if (out != null)\n                    out.close();\n                if (fout != null)\n                    fout.close();\n            }\n            catch(IOException ex)\n            {   \/* Do nothing *\/ }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Finally, let&#8217;s write a program to serialize the&nbsp;<strong>AddressBook<\/strong>&nbsp;back in, and display the <strong>Address<\/strong>es it contains:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.util.Enumeration;\n\npublic class SerializeInAddressBook\n{\n    public static void main(String&#x5B;] args)\n    {\n        AddressBook book = null;\n        FileInputStream fin = null;\n        ObjectInputStream in = null;\n        try\n        {\n            fin = new FileInputStream(&quot;addrbook.ser&quot;);\n            in = new ObjectInputStream(fin);\n            book = (AddressBook) in.readObject();\n            \n            System.out.println(&quot;Serialization successful!&quot;);\n        \n            Enumeration en = book.addresses();\n            while (en.hasMoreElements())\n            {\n                Address addr = (Address) en.nextElement();\n                System.out.println(\n                    &quot;Name: &#x5B;&quot; + addr.getName() + &quot;], &quot; +\n                    &quot;Address: &#x5B;&quot; + addr.getAddress() + &quot;]&quot;);\n            }\n        }\n        catch(ClassNotFoundException ex)\n        {\n            ex.printStackTrace();\n        }\n        catch(IOException ex)\n        {\n            ex.printStackTrace();\n        }\n        finally\n        {\n            try\n            {\n                if (in != null)\n                    in.close();\n                if (fin != null)\n                    fin.close();\n            }\n            catch(IOException ex)\n            {   \/* Do nothing *\/ }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which outputs the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Serialization successful!\nName: [Linus Torvalds], Address: [300 Linux Lane]\nName: [Scott McNealy], Address: [4000 Java Circle]\nName: [Bill Gates], Address: [1000 High-on-the-Hog Drive]<\/strong><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Changing_a_Class\"><\/span>Changing a Class<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">If you simply serialize out with no special handling, then, by default, <strong>ObjectOutputStream<\/strong> will store the fully qualified name of the class being serialized, plus a&nbsp;<em><strong>version number<\/strong><\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This unique version number is computed for the class by applying the <em><strong>Secure Hash Algorithm (SHA)<\/strong><\/em> to the name of the class, its interfaces, fields, and methods. If any such changes are made to the class, the version number will change. This means that a class can become incompatible with its serialized versions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, I added an extra field (a phone number) and modified some methods in the&nbsp;<strong>Address<\/strong>&nbsp;class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [9,12,13,14,15,16,17,29,30,31,32,37]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\n\npublic class Address implements Serializable\n{\n    public Address(String name, String address)\n    {\n        this(name, address, null);\n    }\n    \n    public Address(String name, String address, String phone)\n    {\n        m_name = name;\n        m_address = address;\n        m_phone = phone;\n    }\n    \n    public String getName()\n    {\n        return m_name;\n    }\n    \n    public String getAddress()\n    {\n        return m_address;\n    }\n    \n    public String getPhone()\n    {\n        return m_phone;\n    }\n    \n    \/\/\/\/\/ Private data \/\/\/\/\/\n    private String m_name;\n    private String m_address;\n    private String m_phone;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">But when I try to serialize an older version back in, it gives me the following error, in my Java environment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>java.io.InvalidClassException: serialization.Address; \n      Local class not compatible: stream classdesc serialVersionUID=8364956740597978489 \n                                       local class serialVersionUID=2153101615360274995\n    at java.io.ObjectStreamClass.setClass(ObjectStreamClass.java:242)\n    at java.io.ObjectInputStream.inputClassDescriptor(ObjectInputStream.java:735)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:328)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:225)\n    at java.io.ObjectInputStream.inputObject(ObjectInputStream.java:933)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:344)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:225)\n    at java.util.Hashtable.readObject(Hashtable.java:499)\n    at java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1121)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:344)\n    at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:474)\n    at java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1122)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:344)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:225)\n    at serialization.SerializeInAddressBook.main(SerializeInAddressBook.java:19)\n    at symantec.tools.debug.MainThread.run(Agent.java:48)<\/strong><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Specifying_an_Explicit_Version\"><\/span>Specifying an Explicit Version<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">But we&#8217;d sometimes like to change the class in a way that should not disable the ability to serialize older versions in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In order to do this, we have to specify the version number explicitly.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You do this by specifying a field in your class:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>static final long serialVersionUID = 8364956740597978489L;<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The long numeric literal is the version number. Where did it come from?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The JDK supplies a program called&nbsp;<strong>serialver<\/strong>&nbsp;which can generate a field declaration similar to the above. Once we&#8217;ve used&nbsp;<strong>serialver<\/strong>&nbsp;to determine the version number&nbsp;<em>for the original class<\/em>, we can add this line to the modified class and try it again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voila! The serialization in now works!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we can augment our serialization programs to support the phone number:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [13,16,22]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\n\npublic class SerializeOutAddressBook\n{\n    public static void main(String&#x5B;] args)\n    {\n        AddressBook book = new AddressBook();\n        book.add(&quot;Bill Gates&quot;, &quot;1000 High-on-the-Hog Drive&quot;,\n                                &quot;981-786-5421&quot;);\n        book.add(&quot;Scott McNealy&quot;, &quot;4000 Java Circle&quot;);\n        book.add(&quot;Linus Torvalds&quot;, &quot;300 Linux Lane&quot;,\n                                &quot;653-876-2378&quot;);\n        \n        FileOutputStream fout = null;\n        ObjectOutputStream out = null;\n        try\n        {\n            fout = new FileOutputStream(&quot;addrbook2.ser&quot;);\n            out = new ObjectOutputStream(fout);\n            out.writeObject(book);\n            \n            System.out.println(&quot;Serialization successful!&quot;);\n        }\n        catch(IOException ex)\n        {\n            ex.printStackTrace();\n        }\n        finally\n        {\n            try\n            {\n                if (out != null)\n                    out.close();\n                if (fout != null)\n                    fout.close();\n            }\n            catch(IOException ex)\n            {   \/* Do nothing *\/ }\n        }\n    }\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [35,56]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.util.Enumeration;\n\npublic class SerializeInAddressBook\n{\n    public static void main(String&#x5B;] args)\n    {\n        AddressBook book = null;\n        FileInputStream fin = null;\n        ObjectInputStream in = null;\n        try\n        {\n            Enumeration en = null;\n            \n            System.out.println(&quot;Serializing in addrbook2.ser...&quot;);\n            \n            fin = new FileInputStream(&quot;addrbook2.ser&quot;);\n            in = new ObjectInputStream(fin);\n            book = (AddressBook) in.readObject();\n            \n            System.out.println(\n                    &quot;Serialization of addrbook2.ser successful!&quot;);\n        \n            en = book.addresses();\n            while (en.hasMoreElements())\n            {\n                Address addr = (Address) en.nextElement();\n                System.out.println(\n                    &quot;Name: &#x5B;&quot; + addr.getName() + &quot;], &quot; +\n                    &quot;Address: &#x5B;&quot; + addr.getAddress() + &quot;]&quot; +\n                    &quot;Phone: &#x5B;&quot; + addr.getPhone() + &quot;]&quot;);\n            }\n            \n            in.close();\n            \n            System.out.println(&quot;Serializing in addrbook.ser...&quot;);\n            \n            fin = new FileInputStream(&quot;addrbook.ser&quot;);\n            in = new ObjectInputStream(fin);\n            book = (AddressBook) in.readObject();\n            \n            System.out.println(\n                    &quot;Serialization of addrbook.ser successful!&quot;);\n            \n            en = book.addresses();\n            while (en.hasMoreElements())\n            {\n                Address addr = (Address) en.nextElement();\n                System.out.println(\n                    &quot;Name: &#x5B;&quot; + addr.getName() + &quot;], &quot; +\n                    &quot;Address: &#x5B;&quot; + addr.getAddress() + &quot;]&quot; +\n                    &quot;Phone: &#x5B;&quot; + addr.getPhone() + &quot;]&quot;);\n            }\n            \n        }\n        catch(ClassNotFoundException ex)\n        {\n            ex.printStackTrace();\n        }\n        catch(IOException ex)\n        {\n            ex.printStackTrace();\n        }\n        finally\n        {\n            try\n            {\n                if (in != null)\n                    in.close();\n                if (fin != null)\n                    fin.close();\n            }\n            catch(IOException ex)\n            {   \/* Do nothing *\/ }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This now works correctly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Custom_Serialization_Security\"><\/span>Custom Serialization &amp; Security<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not every item in a class object can, or should be, serialized. Here are some of the issues:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Some objects are inherently specific to the program&#8217;s execution state, and would have no meaning elsewhere.For example, a <strong>FileDescriptor<\/strong> object would have no meaning outside of the program that was using it. Especially on another machine or operating system architecture!<br>Another example is a GUI-based class that retains knowledge of its size based on a calculation previously performed using knowledge of local font sizes. Since font sizes vary from machine to machine, this piece of state would not be useful on another machine.<br>Yet another example: A class that obtains some platform-specific information, such as is available from the system properties. This information should not be serialized out, even if it is only to be used on the same machine type. This is because things may change, even on the same machine: the JDK version may change; the user&#8217;s default directory may change, or even the operating system may change.<\/li><li>Some object state is sensitive, and should not be made available outside of its security domain.For example, a password should not typically be serialized, except in an encrypted form.<\/li><li>Some classes are constructed in a way that guarantees their validity. Serialization provides an opportunity to subvert such guarantees.<br>For example, a&nbsp;<strong>Date<\/strong>&nbsp;object might be constructed in such a way as to make a date of&nbsp;31 February 1999&nbsp;impossible. However, if that object were serialized out to a file, and the file was subsequently tampered with, such an invalid date could be created as a result of serializing it back into memory.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For these reasons, classes are not <strong>Serializable<\/strong> by default. However, what if we wish a class to be <strong>Serializable<\/strong>, but it contains items with such problems?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are two possible solutions:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>We could prevent the sensitive items from being serialized out.<\/li><li>We could allow the sensitive items to be serialized out, but in some special form that does not present any of the above problems.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Preventing_Serialization\"><\/span>Preventing Serialization<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">If you wish an entire class not to be serializable, you can simply not have that class implement&nbsp;<strong>Serializable<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you wish&nbsp;<em>a specific field in a class not to be serialized<\/em>, you can declare it as&nbsp;<strong>transient<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you serialize out a class object, the&nbsp;<strong>writeObject()<\/strong>&nbsp;method will write out information about the class of the object, the signature of the class, and the values of any field&nbsp;<em>that is not transient<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Consider the following example. Here&#8217;s a modified version of the&nbsp;<strong>Person<\/strong>&nbsp;class I used earlier (I&#8217;ve added <strong>setName()<\/strong> and <strong>setAge()<\/strong> methods):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [19,20,21,22,29,30,31,32]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.Serializable;\n\npublic class Person\n    implements Serializable\n{\n    public Person(String name, int age)\n    {\n        m_name = name;\n        m_age  = age;\n    }\n    \n    public String getName()\n    {\n        return m_name;\n    }\n    \n    public void setName(String name)\n    {\n        m_name = name;\n    }\n    \n    public int getAge()\n    {\n        return m_age;\n    }\n    \n    public void setAge(int age)\n    {\n        m_age = age;\n    }\n    \n    public String toString()\n    {\n        String s = getClass().getName();\n        \/\/ Strip off package name\n        int index = s.lastIndexOf(&#039;.&#039;);\n        if (index != -1)\n            s = s.substring(index+1, s.length());\n            \n        s += &quot;:Hashcode=@&quot; + Integer.toHexString(hashCode()) + \n             &quot;, Name=&quot; + m_name + &quot;, Age=&quot; + m_age;\n        return s;\n    }\n    \n    \/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\n    private String  m_name;\n    private int     m_age;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ve also introduced a new class, <strong>RecordedPerson<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.PrintWriter;\n\npublic class RecordedPerson \n    extends Person\n{\n    \/\/ Constructor to create a recorded person and \n    \/\/ the associated record file\n    public RecordedPerson(String name, int age, int id)\n    {\n        super(name, age);\n        m_id = id;\n        createRecordFile();\n    }\n    \n    \/\/ Constructor to create a recorded person\n    \/\/ and to open an already existing record file.\n    public RecordedPerson(int id)\n    {\n        super(null, -1);\n        m_id = id;\n        setRecordFile();\n        setBasicData();\n    }\n    \n    \/\/ Reads the record from the record file\n    \/\/ and returns it as a string.\n    public String getRecord()\n    {\n        String data = &quot;&quot;;\n        BufferedReader in = null;\n        try\n        {\n            in = new BufferedReader(\n                         new FileReader(m_recordFile));\n            while(true)\n            {\n                String line = in.readLine();\n                if (line == null)\n                    break;\n                data += line + &quot;\\n&quot;;\n            }\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (in != null)\n            {\n                try\n                {\n                    in.close();\n                }\n                catch(IOException e)\n                {}\n            }\n        }\n        return data;\n    }\n    \n    \/\/ Adds a new item to the record file for this person\n    public void addRecord(String item)\n    {\n        PrintWriter out = null;\n        try\n        {\n            out = new PrintWriter(\n                        new FileWriter(\n                                m_recordFile.getAbsolutePath(),\n                                true));\n            out.println(item);\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (out != null)\n                out.close();\n        }\n    }\n    \n    \/\/ Creates a new record file with name and age record\n    \/\/ (If the record file already exists, assumes that it&#039;s valid)\n    private void createRecordFile()\n    {\n        setRecordFile();\n        if (!m_recordFile.exists())\n        {\n            \/\/ Create a new record file\n            PrintWriter out = null;\n            try\n            {\n                out = new PrintWriter(\n                                new FileWriter(m_recordFile));\n                out.println(getName() + &quot;,&quot; + getAge());\n            }\n            catch(IOException e)\n            {\n                e.printStackTrace();\n            }\n            finally\n            {\n                if (out != null)\n                    out.close();\n            }\n        }\n        else\n        {\n            \/\/ Assume for simplicity that the name and age\n            \/\/ actually correspond with the current ones.\n        }\n    }\n    \n    \/\/ Sets the record File object\n    \/\/ If necessary, creates the subdirectory for record files.\n    private void setRecordFile()\n    {\n        File records = new File(&quot;records&quot;);\n        if (!records.exists())\n            records.mkdir();    \/\/ Create directory\n        m_recordFile = new File(records, &quot;r&quot; + m_id + &quot;.rec&quot;);\n    }\n    \n    \/\/ Reads the record file and extracts the name and age\n    \/\/ and sets those values for the current recorded person.\n    private void setBasicData()\n    {\n        \/\/ Extract the name and age from the record\n        String record = getRecord();\n        int commaIndex = record.indexOf(&#039;,&#039;);\n        int eolIndex = record.indexOf(&#039;\\n&#039;);\n        String name = record.substring(0, commaIndex);\n        String age = record.substring(commaIndex+1, eolIndex);\n        \/\/ Set the name and age values\n        setName(name);\n        setAge(Integer.parseInt(age));\n    }\n    \n    \/\/ Creates a string containing RecordedPerson information.\n    public String toString()\n    {\n        String s = super.toString();\n        s += &quot;, ID=&quot; + m_id + &quot;, recordFile=&quot; + m_recordFile;\n        return s;\n    }\n    \/\/\/\/ Data \/\/\/\/\n    private int   m_id;\n    private File  m_recordFile;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a program that serializes out a&nbsp;<strong>RecordedPerson<\/strong>&nbsp;object in the normal way:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [11,12,13,14]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.ObjectOutputStream;\n\npublic class RecordedSerializeOut\n{\n    public static void main(String&#x5B;] args)\n    {\n        RecordedPerson rc = new RecordedPerson(\n                                    &quot;Franco Limpone&quot;, 42, 666);\n        System.out.println(&quot;rc: &quot; + rc);                                    \n        System.out.println(rc.getRecord());\n\n        ObjectOutputStream out = null;\n        try\n        {\n            out = new ObjectOutputStream(\n                          new FileOutputStream(\n                                   &quot;recorded.dat&quot;));\n            out.writeObject(rc);\n            System.out.println(&quot;Serialization successful.&quot;);\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n            System.out.println(&quot;Serialization failed.&quot;);\n        }\n        finally\n        {\n            if (out != null)\n            {\n                try\n                {\n                    out.close();\n                }\n                catch(IOException e)\n                {}\n            }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">It outputs the following on my machine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rc: RecordedPerson:Hashcode=@277e21, Name=Franco Limpone, Age=42, ID=666, recordFile=records\\r666.rec\nFranco Limpone,42\nConvicted of Assault &amp; Battery, 14-Dec-1999<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that the record file is&nbsp;<strong>records\\r666.rec<\/strong>, which is not a portable file specification.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If we serialize this back in using the following program:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [18,19,20]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\n\npublic class RecordedSerializeIn\n{\n    public static void main(String&#x5B;] args)\n    {\n        ObjectInputStream in = null;\n        boolean failed = true;\n        try\n        {\n            in = new ObjectInputStream(\n                          new FileInputStream(\n                                   &quot;recorded.dat&quot;));\n            RecordedPerson rc = (RecordedPerson)in.readObject();\n            System.out.println(&quot;rc: &quot; + rc);\n            System.out.println(rc.getRecord());\n            System.out.println(&quot;Serialization successful.&quot;);\n            failed = false;\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        catch(ClassNotFoundException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (in != null)\n            {\n                try\n                {\n                    in.close();\n                }\n                catch(IOException e)\n                {}\n            }\n            if (failed)\n                System.err.println(&quot;Serialization failed.&quot;);\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This program outputs the following on my machine (which is the same machine on which I serialized it out):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rc: RecordedPerson:Hashcode=@277fd2, Name=Franco Limpone, Age=42, ID=666, recordFile=records\\r666.rec\nFranco Limpone,42\nConvicted of Assault &amp; Battery, 14-Dec-1999<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>recordFile<\/strong>&nbsp;is set to&nbsp;<strong>records\\r666.rec<\/strong>, which means that the&nbsp;<strong>File<\/strong>&nbsp;object was successfully serialized out and then back in. However, ask yourself the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What would have happened if the serialization back in had occurred on another machine?<\/li><li>What would have happened if the program which did the serialization back in had a different default user directory from the program which did the serialization out?<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Now, it turns out that the&nbsp;<strong>File<\/strong>&nbsp;class code ensures during serialization in that the separator (<strong>&#8216;\\&#8217;<\/strong>) is correctly set, so presumably the code would work on another machine (although I wouldn&#8217;t necessarily bet on it!).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So let&#8217;s say we don&#8217;t want to take the risk, and so we choose&nbsp;<em><strong>not<\/strong><\/em>&nbsp;to serialize the&nbsp;<strong>recordFile<\/strong>&nbsp;field. We can do this by merely changing one line in RecordedPerson:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>private <\/strong><strong>transient<\/strong><strong> File  m_recordFile;<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">which makes no perceptable difference in the output of the program that serializes out. However, if we run the program that serializes back in, it outputs the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rc: RecordedPerson:Hashcode=@277f8d, Name=Franco Limpone, Age=42, ID=666, recordFile=null\nSerialization failed.\njava.lang.NullPointerException\n    at java.io.FileInputStream.&lt;init&gt;(FileInputStream.java:75)\n    at java.io.FileReader.&lt;init&gt;(FileReader.java:39)\n    at serialization.RecordedPerson.getRecord(RecordedPerson.java:41)\n    at serialization.RecordedSerializeIn.main(RecordedSerializeIn.java:20)\n    at symantec.tools.debug.MainThread.run(Agent.java:48)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So, clearly, the&nbsp;<strong>recordFile<\/strong>&nbsp;field contents did not get serialized out, and its value was set to&nbsp;<strong>null<\/strong>&nbsp;on serialization back in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What to do? We have to do some&nbsp;<em>custom serialization<\/em>&#8230;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Custom_Serialization\"><\/span>Custom Serialization<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Java&#8217;s serialization mechanism provides a mechanism for classes to specify how they wish the serialization to proceed. You can:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>supplement<\/em>&nbsp;the default serialization, or<\/li><li><em>override<\/em>&nbsp;it entirely<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can specify that a class perform custom serialization by defining methods with the signatures:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>private void writeObject(ObjectOutputStream out)\n     throws IOException<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>private void readObject(ObjectInputStream in)\n     throws IOException,\n            ClassNotFoundException<\/strong><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong><em><u>Note:<\/u><\/em><\/strong>&nbsp;These methods must be declared private, and are not declared in any interface (interfaces can only declare public methods).<\/p><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">If you wish to supplement the default serialization, you must ensure that when you implement these methods, they call the default serialization methods:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>private void writeObject(ObjectOutputStream out)\n     throws IOException\n{\n    \/\/ ...\n    out.defaultWriteObject();\n    \/\/ ...\n}<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>private void readObject(ObjectInputStream in)\n     throws IOException,\n            ClassNotFoundException\n{\n    \/\/ ...\n    in.defaultReadObject();\n    \/\/ ...\n}<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So let&#8217;s modify the&nbsp;<strong>RecordedPerson<\/strong>&nbsp;class to augment the default serialization on input:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [8,158,159,160,161,162,163,164,165,169]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.PrintWriter;\n\npublic class RecordedPerson \n    extends Person\n{\n    \/\/ Constructor to create a recorded person and \n    \/\/ the associated record file\n    public RecordedPerson(String name, int age, int id)\n    {\n        super(name, age);\n        m_id = id;\n        createRecordFile();\n    }\n    \n    \/\/ Constructor to create a recorded person\n    \/\/ and to open an already existing record file.\n    public RecordedPerson(int id)\n    {\n        super(null, -1);\n        m_id = id;\n        setRecordFile();\n        setBasicData();\n    }\n    \n    \/\/ Reads the record from the record file\n    \/\/ and returns it as a string.\n    public String getRecord()\n    {\n        String data = &quot;&quot;;\n        BufferedReader in = null;\n        try\n        {\n            in = new BufferedReader(\n                         new FileReader(m_recordFile));\n            while(true)\n            {\n                String line = in.readLine();\n                if (line == null)\n                    break;\n                data += line + &quot;\\n&quot;;\n            }\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (in != null)\n            {\n                try\n                {\n                    in.close();\n                }\n                catch(IOException e)\n                {}\n            }\n        }\n        return data;\n    }\n    \n    \/\/ Adds a new item to the record file for this person\n    public void addRecord(String item)\n    {\n        PrintWriter out = null;\n        try\n        {\n            out = new PrintWriter(\n                        new FileWriter(\n                                m_recordFile.getAbsolutePath(),\n                                true));\n            out.println(item);\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (out != null)\n                out.close();\n        }\n    }\n    \n    \/\/ Creates a new record file with name and age record\n    \/\/ (If the record file already exists, assumes that it&#039;s valid)\n    private void createRecordFile()\n    {\n        setRecordFile();\n        if (!m_recordFile.exists())\n        {\n            \/\/ Create a new record file\n            PrintWriter out = null;\n            try\n            {\n                out = new PrintWriter(\n                                new FileWriter(m_recordFile));\n                out.println(getName() + &quot;,&quot; + getAge());\n            }\n            catch(IOException e)\n            {\n                e.printStackTrace();\n            }\n            finally\n            {\n                if (out != null)\n                    out.close();\n            }\n        }\n        else\n        {\n            \/\/ Assume for simplicity that the name and age\n            \/\/ actually correspond with the current ones.\n        }\n    }\n    \n    \/\/ Sets the record File object\n    \/\/ If necessary, creates the subdirectory for record files.\n    private void setRecordFile()\n    {\n        File records = new File(&quot;records&quot;);\n        if (!records.exists())\n            records.mkdir();    \/\/ Create directory\n        m_recordFile = new File(records, &quot;r&quot; + m_id + &quot;.rec&quot;);\n    }\n    \n    \/\/ Reads the record file and extracts the name and age\n    \/\/ and sets those values for the current recorded person.\n    private void setBasicData()\n    {\n        \/\/ Extract the name and age from the record\n        String record = getRecord();\n        int commaIndex = record.indexOf(&#039;,&#039;);\n        int eolIndex = record.indexOf(&#039;\\n&#039;);\n        String name = record.substring(0, commaIndex);\n        String age = record.substring(commaIndex+1, eolIndex);\n        \/\/ Set the name and age values\n        setName(name);\n        setAge(Integer.parseInt(age));\n    }\n    \n    \/\/ Creates a string containing RecordedPerson information.\n    public String toString()\n    {\n        String s = super.toString();\n        s += &quot;, ID=&quot; + m_id + &quot;, recordFile=&quot; + m_recordFile;\n        return s;\n    }\n    \n    private void readObject(ObjectInputStream in)\n        throws IOException,\n                ClassNotFoundException\n    {\n        in.defaultReadObject();\n        \/\/ Ensure that the recordFile is properly set\n        setRecordFile();\n    }\n    \n    \/\/\/\/ Data \/\/\/\/\n    private int   m_id;\n    private transient File  m_recordFile;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Which produces the proper output on serialization back in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rc: RecordedPerson:Hashcode=@278019, Name=Franco Limpone, Age=42, ID=666, recordFile=records\\r666.rec\nFranco Limpone,42\nConvicted of Assault &amp; Battery, 14-Dec-1999<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Adding_Items_to_the_Serialized_Class\"><\/span>Adding Items to the Serialized Class<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">If desired, you can implement your&nbsp;<strong>writeObject()<\/strong>&nbsp;method in a way similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private void writeObject(ObjectOutputStream out)\n     throws IOException\n{\n    out.defaultWriteObject();\n    out.writeObject(myObject);  \/\/ write out additional object\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, if you do this, then you must also do the equivalent when serializing back in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private void readObject(ObjectInputStream in)\n     throws IOException,\n            ClassNotFoundException\n{\n    in.defaultReadObject();\n    myObject = in.readObject(); \/\/ read in additional object\n}<\/code><\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Advanced_Serialization\"><\/span>Advanced Serialization<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Externalizable_Interface\"><\/span>The&nbsp;<strong>Externalizable<\/strong>&nbsp;Interface<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">If a class implements the&nbsp;<strong>Externalizable<\/strong>&nbsp;interface, the <strong>ObjectInputStream<\/strong> and <strong>ObjectOutputStream<\/strong> classes use that object&#8217;s <strong>readExternal()<\/strong> and <strong>writeExternal()<\/strong> methods to read and write its state during serialization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>Externalizable<\/strong>&nbsp;interface extends from&nbsp;<strong>Serializable<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage java.io;\n\nimport java.io.ObjectOutput;\nimport java.io.ObjectInput;\n\npublic interface Externalizable extends java.io.Serializable {\n    \/**\n     * The object implements the writeExternal method to save its contents\n     * by calling the methods of DataOutput for its primitive values or\n     * calling the writeObject method of ObjectOutput for objects, strings\n     * and arrays.\n     * @exception IOException Includes any I\/O exceptions that may occur\n     * @since     JDK1.1\n     *\/\n    void writeExternal(ObjectOutput out) throws IOException;\n\n    \/**\n     * The object implements the readExternal method to restore its\n     * contents by calling the methods of DataInput for primitive\n     * types and readObject for objects, strings and arrays.  The\n     * readExternal method must read the values in the same sequence\n     * and with the same types as were written by writeExternal.\n     * @exception ClassNotFoundException If the class for an object being\n     *              restored cannot be found.\n     * @since     JDK1.1\n     *\/\n    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">By implementing&nbsp;<strong>Externalizable<\/strong>, a class can control whether the state of superclasses is stored in the stream, and exactly which fields are stored. Only the identity of an Externalized object is automatically saved by the stream; the class is responsible for writing and reading its contents, and must coordinate with its superclasses to do so.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unlike&nbsp;<strong>Serializable<\/strong>, the&nbsp;<strong>Externalizable<\/strong>&nbsp;interface does not handle code versioning automatically &#8212; you must provide your own.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because the state of an&nbsp;<strong>Externalizable<\/strong>&nbsp;object&#8217;s superclasses can be indirectly manipulated by the <strong>writeExternal()<\/strong> and <strong>readExternal()<\/strong> methods, which are&nbsp;public, you should use&nbsp;<strong>Externalizable<\/strong>&nbsp;with extreme caution to avoid security problems.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_ObjectInputValidation_Interface\"><\/span>The&nbsp;<strong>ObjectInputValidation<\/strong>&nbsp;Interface<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Sometimes you go to great pains to construct a set of objects correctly, usually by putting the appropriate code in the class constructor(s). However, because restoring a set of&nbsp;<strong>Serializable<\/strong>&nbsp;objects does not invoke their constructors, it is often desireable to ensure that the reconstructed object is indeed valid. The&nbsp;<strong>ObjectInputValidation<\/strong>&nbsp;interface provides such capabilities.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here is what it looks like:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage java.io;\n\n\/**\n * Callback interface to allow validation of objects within a graph.\n * Allows an object to be called when a complete graph of objects has\n * been deserialized.\n *\/\npublic interface ObjectInputValidation {\n    \/**\n     * Validates the object\n     * @exception InvalidObjectException If the object cannot validate itself.\n     * @since     JDK1.1\n     *\/\n    public void validateObject() throws InvalidObjectException;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>ObjectInputStream<\/strong>&nbsp;uses a registration scheme to allow you to register an <strong>ObjectInputValidation<\/strong> object during serialization in.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if we take the RecordedPerson class we used to do custom serialization earlier, and add to it support for validation, we get the following class, with highlighted changes:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [7,10,15,165,171,172,173,174,175,176]; title: ; quick-code: false; notranslate\" title=\"\">\npackage serialization;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.FileWriter;\nimport java.io.InvalidObjectException;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.io.ObjectInputValidation;\nimport java.io.PrintWriter;\n\npublic class RecordedPerson \n    extends Person\n    implements ObjectInputValidation\n{\n    \/\/ Constructor to create a recorded person and \n    \/\/ the associated record file\n    public RecordedPerson(String name, int age, int id)\n    {\n        super(name, age);\n        m_id = id;\n        createRecordFile();\n    }\n    \n    \/\/ Constructor to create a recorded person\n    \/\/ and to open an already existing record file.\n    public RecordedPerson(int id)\n    {\n        super(null, -1);\n        m_id = id;\n        setRecordFile();\n        setBasicData();\n    }\n    \n    \/\/ Reads the record from the record file\n    \/\/ and returns it as a string.\n    public String getRecord()\n    {\n        String data = &quot;&quot;;\n        BufferedReader in = null;\n        try\n        {\n            in = new BufferedReader(\n                         new FileReader(m_recordFile));\n            while(true)\n            {\n                String line = in.readLine();\n                if (line == null)\n                    break;\n                data += line + &quot;\\n&quot;;\n            }\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (in != null)\n            {\n                try\n                {\n                    in.close();\n                }\n                catch(IOException e)\n                {}\n            }\n        }\n        return data;\n    }\n    \n    \/\/ Adds a new item to the record file for this person\n    public void addRecord(String item)\n    {\n        PrintWriter out = null;\n        try\n        {\n            out = new PrintWriter(\n                        new FileWriter(\n                                m_recordFile.getAbsolutePath(),\n                                true));\n            out.println(item);\n        }\n        catch(IOException e)\n        {\n            e.printStackTrace();\n        }\n        finally\n        {\n            if (out != null)\n                out.close();\n        }\n    }\n    \n    \/\/ Creates a new record file with name and age record\n    \/\/ (If the record file already exists, assumes that it&#039;s valid)\n    private void createRecordFile()\n    {\n        setRecordFile();\n        if (!m_recordFile.exists())\n        {\n            \/\/ Create a new record file\n            PrintWriter out = null;\n            try\n            {\n                out = new PrintWriter(\n                                new FileWriter(m_recordFile));\n                out.println(getName() + &quot;,&quot; + getAge());\n            }\n            catch(IOException e)\n            {\n                e.printStackTrace();\n            }\n            finally\n            {\n                if (out != null)\n                    out.close();\n            }\n        }\n        else\n        {\n            \/\/ Assume for simplicity that the name and age\n            \/\/ actually correspond with the current ones.\n        }\n    }\n    \n    \/\/ Sets the record File object\n    \/\/ If necessary, creates the subdirectory for record files.\n    private void setRecordFile()\n    {\n        File records = new File(&quot;records&quot;);\n        if (!records.exists())\n            records.mkdir();    \/\/ Create directory\n        m_recordFile = new File(records, &quot;r&quot; + m_id + &quot;.rec&quot;);\n    }\n    \n    \/\/ Reads the record file and extracts the name and age\n    \/\/ and sets those values for the current recorded person.\n    private void setBasicData()\n    {\n        \/\/ Extract the name and age from the record\n        String record = getRecord();\n        int commaIndex = record.indexOf(&#039;,&#039;);\n        int eolIndex = record.indexOf(&#039;\\n&#039;);\n        String name = record.substring(0, commaIndex);\n        String age = record.substring(commaIndex+1, eolIndex);\n        \/\/ Set the name and age values\n        setName(name);\n        setAge(Integer.parseInt(age));\n    }\n    \n    \/\/ Creates a string containing RecordedPerson information.\n    public String toString()\n    {\n        String s = super.toString();\n        s += &quot;, ID=&quot; + m_id + &quot;, recordFile=&quot; + m_recordFile;\n        return s;\n    }\n    \n    private void readObject(ObjectInputStream in)\n        throws IOException,\n                ClassNotFoundException\n    {\n        in.registerValidation(this, 0);\n        in.defaultReadObject();\n        \/\/ Ensure that the recordFile is properly set\n        setRecordFile();\n    }\n    \n    public void validateObject() \n        throws InvalidObjectException\n    {\n        if (getAge() &gt; 40)\n            throw new InvalidObjectException(&quot;No persons over 40 allowed&quot;);\n    }\n    \n    \/\/\/\/ Data \/\/\/\/\n    private int   m_id;\n    private transient File  m_recordFile;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now, when we attempt to serialize this class back in, we now get the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>java.io.InvalidObjectException: No persons over 40 allowed\n    at serialization.RecordedPerson.validateObject(RecordedPerson.java:175)\n    at java.io.ObjectInputStream.doValidations(ObjectInputStream.java:548)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:437)\n    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:225)\n    at serialization.RecordedSerializeIn.main(RecordedSerializeIn.java:18)\n    at symantec.tools.debug.MainThread.run(Agent.java:48)\nSerialization failed.<\/strong><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>One disadvantage of storing objects in memory, during program execution, is that those objects only exist until the program terminates, at which point their contents are lost. Wouldn&#8217;t it be nice if somehow the state of interesting objects could be saved and later restored, so that the program could maintain its state over multiple program [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":19,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_eb_attr":"","ocean_front_end_style_editor":"no","ocean_post_layout":"left-sidebar","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"ocs-course-topics-sidebar","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","footnotes":""},"class_list":["post-194","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":24,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/194\/revisions"}],"predecessor-version":[{"id":396,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/194\/revisions\/396"}],"up":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/pages\/19"}],"wp:attachment":[{"href":"https:\/\/bhiggs.x10hosting.com\/HighOctaneJava\/wp-json\/wp\/v2\/media?parent=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}