- 我们可以通过序列化来保存一个对象的状态(实例变量)到文件中,也可以从这个格式化的文件中很容易地读取对象的状态从而可以恢复我们保存的对象。
-
我们可以通过序列化来保存一个对象的状态(实例变量)到文件中,也可以从这个格式化的文件中很容易地读取对象的状态从而可以恢复我们保存的对象。
对象序列化就是把对象写入到输出流中,用来存储或者传输。
对象的反序列化就是从输入流中读取对象。
用来实现序列化的类都在java.io包中,我们常用的类或接口有:
ObjectOutputStream:提供序列化对象并把其写入流的方法
ObjectInputStream:读取流并反序列化对象
Serializable:一个对象想要被序列化,那么它的类就要实现 此接口,这个对象的所有属性(包括private属性、包括其引用的对象)都可以被序列化和反序列化来保存、传递。
Externalizable:他是Serializable接口的子类,有时我们不希望序列化那么多,可以使用这个接口,这个接口的writeExternal()和readExternal()方法可以指定序列化哪些属性;
但是如果你只想隐藏一个属性,比如用户对象user的密码pwd,如果使用Externalizable,并除了pwd之外的每个属性都写在writeExternal()方法里,这样显得麻烦,可以使用Serializable接口,并在要隐藏的属性pwd前面加上transient就可以实现了。
- import java.io.*;
- /**
- * Java对象的序列化测试
- * File: ObjectStreamTest.java
- * User: leizhimin
- * Date: 2008-3-12 20:41:43
- */
- public class ObjectStreamTest {
- public static void main(String args[]) {
- testObjectSeri();
- testObjectInSeri();
- }
- /**
- * 对象序列化测试
- */
- public static void testObjectSeri() {
- Person person = new Person("熔岩", "341022225562156", "lavasoft");
- FileOutputStream fos = null;
- ObjectOutputStream oos = null;
- try {
- fos = new FileOutputStream("Q:\\study\\java5study\\src\\io\\person.dat");
- oos = new ObjectOutputStream(fos);
- oos.writeObject(person);
- } catch (FileNotFoundException e) {
- System.out.println("找不到指定的文件!");
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- oos.flush();
- oos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 对象反序列化测试
- */
- public static void testObjectInSeri() {
- FileInputStream fis = null;
- ObjectInputStream ois = null;
- Person person = null;
- try {
- fis = new FileInputStream("Q:\\study\\java5study\\src\\io\\person.dat");
- ois = new ObjectInputStream(fis);
- person = (Person) ois.readObject();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } finally {
- try {
- ois.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- System.out.println(person.toString());
- }
- }
- /**
- * 测试序列化所用的类
- */
- class Person implements Serializable {
- private String username;
- private String cardNumber;
- private transient String password;
- public Person(String username, String cardNumber, String password) {
- this.username = username;
- this.cardNumber = cardNumber;
- this.password = password;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getCardNumber() {
- return cardNumber;
- }
- public void setCardNumber(String cardNumber) {
- this.cardNumber = cardNumber;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(this.getClass().getName());
- sb.append("[");
- sb.append("\n\t");
- sb.append("username=" + this.username);
- sb.append("\n\t");
- sb.append("cardNumber=" + this.cardNumber);
- sb.append("\n\t");
- sb.append("password=" + this.password);
- sb.append("]");
- return sb.toString();
- }
- }
import java.io.*; /** * Java对象的序列化测试 * File: ObjectStreamTest.java * User: leizhimin * Date: 2008-3-12 20:41:43 */ public class ObjectStreamTest { public static void main(String args[]) { testObjectSeri(); testObjectInSeri(); } /** * 对象序列化测试 */ public static void testObjectSeri() { Person person = new Person("熔岩", "341022225562156", "lavasoft"); FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream("Q:\\study\\java5study\\src\\io\\person.dat"); oos = new ObjectOutputStream(fos); oos.writeObject(person); } catch (FileNotFoundException e) { System.out.println("找不到指定的文件!"); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.flush(); oos.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 对象反序列化测试 */ public static void testObjectInSeri() { FileInputStream fis = null; ObjectInputStream ois = null; Person person = null; try { fis = new FileInputStream("Q:\\study\\java5study\\src\\io\\person.dat"); ois = new ObjectInputStream(fis); person = (Person) ois.readObject(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println(person.toString()); } } /** * 测试序列化所用的类 */ class Person implements Serializable { private String username; private String cardNumber; private transient String password; public Person(String username, String cardNumber, String password) { this.username = username; this.cardNumber = cardNumber; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getCardNumber() { return cardNumber; } public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String toString() { StringBuffer sb = new StringBuffer(this.getClass().getName()); sb.append("["); sb.append("\n\t"); sb.append("username=" + this.username); sb.append("\n\t"); sb.append("cardNumber=" + this.cardNumber); sb.append("\n\t"); sb.append("password=" + this.password); sb.append("]"); return sb.toString(); } }
运行结果如下:
- io.Person[
- username=熔岩
- cardNumber=341022225562156
- password=null]
- Process finished with exit code 0
io.Person[ username=熔岩 cardNumber=341022225562156 password=null] Process finished with exit code 0
Serializable接口和Externalizable接口的区别不仅限于此:
Serializable序列化时不会调用默认的构造器,而Externalizable序列化时会调用默认构造器的!!!
其他说明:
1、 基本类型 的数据可以直接序列化
2、 对象要被序列化,它的类必须要实现Serializable接口;如果一个类中有引用类型的实例变量,这个引用类型也要实现Serializable接口。比如上面 的例子中,Student类中有一个Book类型 的实例就是,要想让Student的对象成功序列化,那么Book也必须要实现Serializable接口;
如果不想让Book实现Serializable接口,并且让Student类成功序列化也可以,使用transient关键字。
serialVersionUID作用:序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 有两种生成方式: 一个是默认的1L,比如:private static final long se...
serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
有两种生成方式:
一个是默认的1L,比如:private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
private static final long serialVersionUID = xxxxL;
当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个
提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会
自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也
可以把它关掉的,设置如下:
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
Potential programming problems
将Serializable class without serialVersionUID的warning改成ignore即可。
最后,还有两个问题:
1、 如果一个类没有实现Serializable接口,但是它的基类实现 了,这个类可不可以序列化?
2、 和上面相反,如果一个类实现了Serializable接口,但是它的父类没有实现 ,这个类可不可以序列化?
第1个问题:一个类实现 了某接口,那么它的所有子类都间接实现了此接口,所以它可以被 序列化。
第2个问题:Object是每个类的超类,但是它没有实现 Serializable接口,但是我们照样在序列化对象,所以说明一个类要序列化,它的父类不一定要实现Serializable接口。但是在父类中定义 的状态能被正确 的保存以及读取吗?这个我将在下一篇文章中用一个例子来说明,请见http://blog.csdn.net/moreevan/article/details/6698529
第3个问题:如果将一个对象写入某文件(比如是a),那么之后对这个对象进行一些修改,然后把修改的对象再写入文件a,那么文件a中会包含该对象的两个 版本吗?
相关推荐
java.io.Serializable序列化问题
java 序列化 对象 Serializable 写着玩的Demo 简单 实用
主要介绍了java 中序列化NotSerializableException问题解决办法的相关资料,这里对序列化问题进行描述说明,并提供解决办法,希望能帮助到大家,需要的朋友可以参考下
java.io.Serializable, java.lang.Cloneable, java.util.EventListener, nc.vo.gl.vouchervaluechange.ValueChangeListener, nc.vo.glpub.IVoAccess -----------------------------------------------------------...
java中的IO操作总结(四) 前面已经把java io的主要操作讲完了 这一节我们来说说关于java io的其他内容 Serializable序列化 实例1:对象的序列化 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23...
Java序列化(java.io.Serializable) Hadoop序列化的特点 Hadoop的序列化格式:Writable 序列化格式特点: 紧凑:高效使用存储空间。 快速:读写数据的额外开销小 可扩展:可透明地读取老格式...
java序列化(Serializable)的作用和反序列化.doc 有详细的讲解哦。 在什么地方用的到都有说明的.
序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例...虽然你可以用你自己的各种各样的方法来保 存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
其中包括以下接口和类: java.io.Serializable java.io.Externalizable ObjectOutput ObjectInput ObjectOutputStream ObjectInputStream Java高级程序设计实战教程第五章-Java序列化机制全文共15页,当前为第7页。...
java 的序列化与反序列化举例测试
Java_Serializable(序列化) 的理解和总结
主要介绍了JAVA序列化Serializable及Externalizable区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
导入java.io.Serializable; 导入java.security.AccessController; 导入java.security.AuthProvider; 导入java.security.InvalidParameterException; 导入java.security.Key; 导入java.security....
Serializable接口和Externalizable接口实现序列化和反序列化
Serializable有一个子接口Externalizable,实现Externalizable接口的类可以自行控制对象序列化荷反序列化过程。 一般来说,没有必要自己实现序列化接口,直接交给Java虚拟机是上策。 实现了序列化接口的类,如果...
为什么实现了java.io.Serializable接口才能被序列化 transient的作用是什么 怎么自定义序列化策略 自定义的序列化策略是如何被调用的 ArrayList对序列化的实现有什么好处 Java对象的序列化 ...
NULL 博文链接:https://zhycaf.iteye.com/blog/982092
Java中的序列化机制有两种实现方式: 一种是实现Serializable接口 另一种是实现Externalizable接口 区别: 实现Serializable接口 1 系统自动储存必要的信息 2 Java内建支持,易于实现,只需实现该接口即可,无须任何...
java.lang.Throwable (implements java.io.Serializable) java.lang.Exception java.lang.RuntimeException com.opensymphony.xwork2.XWorkException (implements com.opensymphony.xwork2.util.location.Locatable...
java->serializable深入了解 java->serializable深入了解 java->serializable深入了解