Serializable 序列化的简要说明(原文地址) {#Serializable 序列化的简要说明 - 原文地址}
一、 持久化的简单介绍: {#一、- 持久化的简单介绍:}
"持久化"意味着对象的"生存时间"并不取决于程序是否正在执行------它存在或"生存"于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序再次调用时重新恢复那个对象,就能圆满实现一种"持久"效果。
二、 语言里增加了对象序列化的概念后,可提供对两种主要特性的支持: {#二、- 语言里增加了对象序列化的概念后,可提供对两种主要特性的支持:}
- 远程方法调用(
RMI
)使本来存在于其他机器的对象可以表现出好象就在本地机器上的行为。将消息发给远程对象时,需要通过对象序列化来传输参数和返回值。 - 使用一个
Java Bean
时,它的状态信息通常在设计期间配置好。程序启动以后,这种状态信息必须保存下来,以便程序启动以后恢复;具体工作由对象序列化完成。
三、 Serializable 的一些说明: {#三、-Serializable 的一些说明:}
- 对象的序列化处理非常简单,只需对象实现了
Serializable
接口即可(该接口仅是一个标记,没有方法) - 序列化的对象包括基本数据类型,所有集合类以及其他许多东西,还有
Class
对象 - 对象序列化不仅保存了对象的"全景图",而且能追踪对象内包含的所有句柄并保存那些对象;接着又能对每个对象内包含的句柄进行追踪
- 使用
transient
关键字修饰的的变量,在序列化对象的过程中,该属性不会被序列化。
四、 序列化的步骤: {#四、- 序列化的步骤:}
- 首先要创建某些
OutputStream
对象:
OutputStream outputStream = new FileOutputStream("output.txt")
- 将其封装到
ObjectOutputStream
对象内:
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
- 此后只需调用
writeObject()
即可完成对象的序列化,并将其发送给
OutputStream:objectOutputStream.writeObject(Object);
- 最后不要忘记关闭资源:
objectOutputStream.close(), outputStream .close();
五、 反序列化的步骤: {#五、- 反序列化的步骤:}
- 首先要创建某些
OutputStream
对象:
InputStream inputStream= new FileInputStream("output.txt")
- 将其封装到 ObjectInputStream 对象内:
ObjectInputStream objectInputStream= new ObjectInputStream(inputStream);
- 此后只需调用 readObject()即可完成对象的反序列化:
objectInputStream.readObject();
- 最后不要忘记关闭资源:
objectInputStream.close(),inputStream.close();
Serializable 的一些说明 {#Serializable 的一些说明}
- 对象的序列化处理非常简单,只需对象实现了 Serializable 接口即可(该接口仅是一个标记,没有方法)
- 序列化的对象包括基本数据类型,所有集合类以及其他许多东西,还有
Class
对象 - 对象序列化不仅保存了对象的"全景图",而且能追踪对象内包含的所有句柄并保存那些对象;接着又能对每个对象内包含的句柄进行追踪
- 使用
transient
关键字修饰的的变量,在序列化对象的过程中,该属性不会被序列化。
Serializable 序列化的代码实例 {#Serializable 序列化的代码实例}
一、 首先我们建立一个 Man 类,实现了 Serializable 接口,用于 Person 类的测试:
public class Man implements Serializable {
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">long</span> serialVersionUID <span class="token operator">=</span> <span class="token number">1L</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">String</span> passworld<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token class-name">Man</span><span class="token punctuation">(</span><span class="token class-name">String</span> username<span class="token punctuation">,</span> <span class="token class-name">String</span> passworld<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token operator">=</span> username<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>passworld <span class="token operator">=</span> passworld<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> username<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUsername</span><span class="token punctuation">(</span><span class="token class-name">String</span> username<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token operator">=</span> username<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getPassworld</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> passworld<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPassworld</span><span class="token punctuation">(</span><span class="token class-name">String</span> passworld<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>passworld <span class="token operator">=</span> passworld<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
二、 我们再建立一个 Person 类,用于序列化:
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private Man man;
private String username;
private transient int age;
<span class="token keyword">public</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"person constru"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token class-name">Man</span> man<span class="token punctuation">,</span> <span class="token class-name">String</span> username<span class="token punctuation">,</span> <span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>man <span class="token operator">=</span> man<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token operator">=</span> username<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token class-name">Man</span> <span class="token function">getMan</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> man<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMan</span><span class="token punctuation">(</span><span class="token class-name">Man</span> man<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>man <span class="token operator">=</span> man<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> username<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUsername</span><span class="token punctuation">(</span><span class="token class-name">String</span> username<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token operator">=</span> username<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span><span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
三、 编写一个包含 main 方法的测试类:MainTest,它的 writeSerializableObject 用于序列化对象:
public static void writeSerializableObject() {
try {
Man man = new Man("root", "123456");
Persion persion = new Persion(man, "墨白", 21);
OutputStream out;
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("output.txt"));
o.writeObject("String");
o.writeObject(persion);
o.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
四、 测试类 MainTest
,它的readSerializableObject
用于反序列化对象:
// Serializable:反序列化对象
public static void readSerializableObject() {
try {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("output.txt"));
String string = (String) objectInputStream.readObject();
Persion person = (Persion) objectInputStream.readObject();
objectInputStream.close();
System.out.println(string + ", age:" + person.getAge() + ", man username:" + person.getMan().getUsername());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
五、 在 Main
方法添加以上两个方法的运行,结果如下:
String, age: 0, man username: root
- 在
Person
类中包含Man
的引用,当Person
被序列化的时候,从结果可以知道Man
也被序列化了 writeObject
方法可以传入String
,是因为String
首先是一个类,其次它也是实现了Serializable
接口的Person
类中的age
字段是transient
,从打印结果可以看到,序列化Person person = new Person(man, " 刘力 ", 21)
对象时,age
没有进行序列化。如果transient
修饰的Object
类型的,那么打印的结果将会是null
相关注意事项 {#相关注意事项}
-
序列化时,只对对象的状态进行保存,而不管对象的方法;
-
当一个父类实现序列化,子类自动实现序列化,不需要显式实现
Serializable
接口; -
当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
-
并非所有的对象都可以序列化,, 至于为什么不可以,有很多原因了, 比如:
- 安全方面的原因,比如一个对象拥有 private,public 等 field,对于一个要传输的对象,比如写到文件,或者进行 rmi 传输 等等,在序列化进行传输的过程中,这个对象的 private 等域是不受保护的。
- 资源分配方面的原因,比如 socket,thread 类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分 配,而且,也是没有必要这样实现。