Java序列化(持久化)

<div id="article_content" class="article_content csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post">
                    <div class="markdown_views">
                <p>参考了<a href="http://www.runoob.com/java/java-serialization.html" target="_blank">菜鸟教程</a> 和 <a href="http://beautyboss.farbox.com/post/study/shen-ru-xue-xi-javaxu-lie-hua" target="_blank">天凉好个秋</a></p>


<h3 id="什么是java序列化"><a name="t0"></a>什么是Java序列化</h3>


<p>Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。</p>


<p>将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。</p>


<h3 id="使用场景"><a name="t1"></a>使用场景</h3>


<ol>
<li><p>一般情况下Java对象的声明周期都比Java虚拟机的要短,实际应用中我们希望在JVM停止运行之后能够持久化指定的对象,这时候就需要把对象进行序列化之后保存。</p></li>
<li><p>需要把Java对象通过网络进行传输的时候。因为数据只能够以二进制的形式在网络中进行传输,因此当把对象通过网络发送出去之前需要先序列化成二进制数据,在接收端读到二进制数据之后反序列化成Java对象。</p></li>
</ol>


<h3 id="序列化方法"><a name="t2"></a>序列化方法</h3>


<p>类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。</p>


<pre class="prettyprint"><code class="has-numbering">public final void writeObject(Object x) throws IOException
</code><ul class="pre-numbering"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre>


<p>上面的方法序列化一个对象,并将它发送到输出流。相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:</p>


<pre class="prettyprint"><code class="has-numbering">public final Object readObject() throws IOException, ClassNotFoundException
</code><ul class="pre-numbering"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre>


<p>该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。</p>


<p><strong>注意</strong> <br>
一个类的对象要想序列化成功,必须满足两个条件:</p>


<ol>
<li><p>该类必须实现 java.io.Serializable 对象。</p></li>
<li><p>该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂(transient)的。或如果有不想序列化的属性,也声明为transient,当对该类序列化时,会自动忽略被 transient 修饰的属性。</p></li>
</ol>






<h3 id="举例"><a name="t3"></a>举例</h3>


<p>序列化类 <code>Employee</code> 的一个对象,类文件代码:</p>


<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">java</span>.<span class="hljs-title">io</span>.<span class="hljs-title">Serializable</span>
{</span>
   <span class="hljs-keyword">public</span> String name;
   <span class="hljs-keyword">public</span> String address;
   <span class="hljs-keyword">public</span> <span class="hljs-keyword">transient</span> <span class="hljs-keyword">int</span> SSN;
   <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> number;
   <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">mailCheck</span>()
   {
      System.out.println(<span class="hljs-string">"Mailing a check to "</span> + name
                           + <span class="hljs-string">" "</span> + address);
   }
}</code><ul class="pre-numbering"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li></ul></pre>


<ul>
<li><p>序列化对象</p>


<p>ObjectOutputStream 类用来序列化一个对象,如下的 SerializeDemo 例子实例化了一个 Employee 对象,并将该对象序列化到一个文件中。</p>


<p>该程序执行后,就创建了一个名为 employee.ser 文件。当序列化一个对象到文件时, 按照 Java 的标准约定是给文件一个 .ser 扩展名。</p>


<pre class="prettyprint" name="code"><code class="hljs cs has-numbering">import java.io.*;


<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> SerializeDemo
{
   <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String [] args)
   {
      Employee e = <span class="hljs-keyword">new</span> Employee();
      e.name = <span class="hljs-string">"Reyan Ali"</span>;
      e.address = <span class="hljs-string">"Phokka Kuan, Ambehta Peer"</span>;
      e.SSN = <span class="hljs-number">11122333</span>;
      e.number = <span class="hljs-number">101</span>;
      <span class="hljs-keyword">try</span>
      {
         FileOutputStream fileOut =
         <span class="hljs-keyword">new</span> FileOutputStream(<span class="hljs-string">"employee.ser"</span>);
         ObjectOutputStream <span class="hljs-keyword">out</span> = <span class="hljs-keyword">new</span> ObjectOutputStream(fileOut);
         <span class="hljs-keyword">out</span>.writeObject(e);
         <span class="hljs-keyword">out</span>.close();
         fileOut.close();
         System.<span class="hljs-keyword">out</span>.printf(<span class="hljs-string">"Serialized data is saved in /tmp/employee.ser"</span>);
      }<span class="hljs-keyword">catch</span>(IOException i)
      {
          i.printStackTrace();
      }
   }
}</code><ul class="pre-numbering"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li></ul></pre>


<p>以下是employee.ser存储的内容: <br>
<img src="https://img-blog.csdn.net/20180512165103533?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dheW5lNTY2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述" title=""></p></li>
<li><p>反序列化对象</p>


<p>下面的 DeserializeDemo 程序实例了反序列化,employee.ser 存储了 Employee 对象。</p>


<pre class="prettyprint" name="code"><code class="hljs cs has-numbering">import java.io.*;


<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> DeserializeDemo
{
   <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String [] args)
   {
      Employee e = <span class="hljs-keyword">null</span>;
      <span class="hljs-keyword">try</span>
      {
         FileInputStream fileIn = <span class="hljs-keyword">new</span> FileInputStream(<span class="hljs-string">"employee.ser"</span>);
         ObjectInputStream <span class="hljs-keyword">in</span> = <span class="hljs-keyword">new</span> ObjectInputStream(fileIn);
         e = (Employee) <span class="hljs-keyword">in</span>.readObject();
         <span class="hljs-keyword">in</span>.close();
         fileIn.close();
      }<span class="hljs-keyword">catch</span>(IOException i)
      {
         i.printStackTrace();
         <span class="hljs-keyword">return</span>;
      }<span class="hljs-keyword">catch</span>(ClassNotFoundException c)
      {
         System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Employee class not found"</span>);
         c.printStackTrace();
         <span class="hljs-keyword">return</span>;
      }
      System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Deserialized Employee..."</span>);
      System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Name: "</span> + e.name);
      System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Address: "</span> + e.address);
      System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"SSN: "</span> + e.SSN);
      System.<span class="hljs-keyword">out</span>.println(<span class="hljs-string">"Number: "</span> + e.number);
      e.mailCheck();
    }
}</code><ul class="pre-numbering"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li></ul></pre>


<p>以上程序编译运行结果如下所示:</p>


<pre class="prettyprint" name="code"><code class="hljs avrasm has-numbering">Deserialized Employee...
<span class="hljs-label">Name:</span> Reyan Ali
<span class="hljs-label">Address:</span> Phokka Kuan, Ambehta Peer
<span class="hljs-label">SSN:</span> <span class="hljs-number">0</span>
<span class="hljs-label">Number:</span> <span class="hljs-number">101</span>
Mailing a check to Reyan Ali Phokka Kuan, Ambehta Peer</code><ul class="pre-numbering"><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre>


<p>这里要注意以下要点:</p>


<ul><li><p>readObject() 方法中的 try/catch代码块尝试捕获 ClassNotFoundException 异常。对于 JVM 可以反序列化对象,它必须是能够找到字节码的类。如果JVM在反序列化对象的过程中找不到该类,则抛出一个 ClassNotFoundException 异常。</p>


<p>注意,readObject() 方法的返回值被转化成 Employee 引用。</p></li>
<li><p>当对象被序列化时,属性 SSN 的值为 111222333,但是因为该属性是短暂的,该值没有被发送到输出流。所以反序列化后 Employee 对象的 SSN 属性为 0。</p></li></ul></li>
</ul>            </div>
            <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
                </div>

猜你喜欢

转载自blog.csdn.net/wuyin9/article/details/80303979