动车上的书摘-java对象流与序列化

论坛 期权论坛     
选择匿名的用户   2021-5-29 19:23   11   0
<div class="blogpost-body" id="cnblogs_post_body">
<p>摘要: 摘要: 原创出处: <span style="color:#9bbb59;">http://www.cnblogs.com/Alandre/</span> 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢!</p>
<h5><span style="color:#9b00d3;">钢笔不限贵便宜,书法是来自心对手的交流。-泥沙砖瓦浆木匠</span></h5>
<p> </p>
<h1 id="jeffli01">一.对象序列化</h1>
<p>当需要存储相同类型的数据,选择固定的长度记录是好选择。但是在面向对象(OOP)程序中,对象之间很少有全部相同的类型。所以,java语言支持一种称为对象序列化(object serialization)的机制。</p>
<p>下面展示一个序列化例子,关于两个对象 Employee 和 Manager 。首先我们必须先把他们存储进去:</p>
<div class="cnblogs_code" style="border:#cccccc 1px solid;">
  <pre class="blockcode">ObjectOutputStream out &#61; <span style="color:#0000ff;">new</span> ObjectOutputStream( <span style="color:#0000ff;">new</span> FileOutputStream(&#34;employee.bat&#34;<span style="color:#000000;">));
Employee employee </span>&#61; <span style="color:#0000ff;">new</span> Employee(&#34;Employee one &#34;,5000,1989,10,1<span style="color:#000000;">);
Manager  boss     </span>&#61; <span style="color:#0000ff;">new</span> Manager(&#34;Manager one &#34;,8000,1987,7,1<span style="color:#000000;">);
out.writeObject(employee);
out.writeObject(boss);</span></pre>
</div>
<p>为了将这些对象读回,首先要获取一个ObjectInputStream对象,然后用readObject方法获得它们。</p>
<div class="cnblogs_code" style="border:#cccccc 1px solid;">
  <pre class="blockcode">ObjectInputStream in &#61; <span style="color:#0000ff;">new</span> ObjectInputStream(<span style="color:#0000ff;">new</span> FileOutputStream(&#34;employee.bat&#34;<span style="color:#000000;">));
Employee e </span>&#61;<span style="color:#000000;"> (Employee)in.readObject();
Manager  b </span>&#61; (Manager)in.readObject();</pre>
</div>
<p>总而言之,这些希望在对象流存储或者恢复的所有类,必训实现public interface <strong>Serializable</strong></p>
<pre class="blockcode"></pre>
<p>类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。</p>
<p> </p>
<p>其他除了<code>writeObject方法,常用操作的api:</code></p>
<h2>java.io.ObjectOutputStream</h2>
<p><code><strong>writeDouble</strong>(double val)</code><br>          写入一个 64 位的 double 值。<br><code><strong>writeFields</strong>()</code><br>          将已缓冲的字段写入流中。<br><code><strong>writeFloat</strong>(float val)</code><br>          写入一个 32 位的 float 值。<br><code><strong>writeInt</strong>(int val)</code><br>          写入一个 32 位的 int 值。<br><code><strong>writeLong</strong>(long val)</code><br>          写入一个 64 位的 long 值。<br><code><strong>writeObject</strong>(Object obj)</code><br>          将指定的对象写入 ObjectOutputStream。</p>
<p> </p>
<h1 id="jeffli02">二.对象序列化中的算法 </h1>
<p>就像上面说的,两个Manager 的员工可能是同一个Employee。伪代码如下:</p>
<div class="cnblogs_code" style="border:#cccccc 1px solid;">
  <pre class="blockcode">Employee employee &#61; <span style="color:#0000ff;">new</span> Employee(&#34;Employee one &#34;<span style="color:#000000;">);
Manager a </span>&#61; <span style="color:#0000ff;">new</span> Manager(&#34;Manager a&#34;<span style="color:#000000;">);
a.setWorker(employee);
Manager b </span>&#61; <span style="color:#0000ff;">new</span> Manager(&#34;Manager b&#34;<span style="color:#000000;">);
a.setWorker(employee);</span></pre>
</div>
<p><span style="font-family:&#39;微软雅黑&#39;;">对保存这样的对象,没使用序列化是一种挑战。当类被重新加载时,他可能占据的是原来完全不同的内存地址。对象序列化的原因是:每个对象都用一个序列号(serial number)保存的。如图(两个管理拥有同一个工作人员):</span></p>
<p><span style="font-family:&#39;微软雅黑&#39;;"><a href="https://images0.cnblogs.com/blog/509099/201407/171742590216630.png"><img alt="Unnamed QQ Screenshot20140717164755" border="0" height="338" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-c7a8ab98105b0d71a9697858e2c08ec4.png" style="background-image:none;border-width:0px;" title="Unnamed QQ Screenshot20140717164755" width="716"></a></span></p>
<p><span style="font-family:&#39;微软雅黑&#39;;">Java的序列化算法序列化算法一般会按步骤做如下事情:</span></p>
<p align="left">◆将对象实例相关的类元数据输出。</p>
<p align="left">◆递归地输出类的超类描述直到不再有超类。</p>
<p align="left">◆类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。</p>
<p align="left">◆从上至下递归输出实例的数据</p>
<
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP