Java对象的序列化
来源:互联网 发布:民族性格知乎 编辑:程序博客网 时间:2024/04/30 09:49
Java对象的序列化
有时候我们有这样的需求:
将对象(不是文件)在客户端和服务器端进行传递;
将对象存储到外存的文件中,并能够从文件中回复对象。
概念
序列化:(也叫串行化)就是把对象转换成字节的流的形式(由于对象存储的内容千差万别,这种流不可能是字符流,只能是字节流);
反序列化:从字节流中重构出对象的过程。
对象图:Java的序列机制能够自动搜索与被序列化对象密切相关的对象,并建立起一个描述关系的网络(要序列化a引用的对象,而对象中又有成员引用了B类对象,B类对象中又有成员引用了C类对象,如何处理?除非明确说明不序列化(transient关键字),否则将自动序列化其他的)。
Serializable接口:只有实现了Serializable接口的类,其对象才能被序列化或反序列化;Serializable接口中没有属性和方法,仅仅是一种让JVM解读的标识;实现这一接口的类,将被纳入对象图的搜索范围中。
源码实例
/** * 实现把一个对象写入文件,并且从这个文件恢复这个对象 * @author jin */public class Test1 {public static void main(String[] args) {A a=new A("Joyce", 22);System.out.println("创建一个对象a, name="+a.getName()+", age="+a.getAge());File file=new File("object.odt");try {FileOutputStream fos=new FileOutputStream(file);ObjectOutputStream oos=new ObjectOutputStream(fos);oos.writeObject(a);} catch (FileNotFoundException e) {e.printStackTrace();}catch(IOException e1){e1.printStackTrace();}try {FileInputStream fis=new FileInputStream(file);ObjectInputStream ois=new ObjectInputStream(fis);A b=(A)ois.readObject();System.out.println("从文中读出对象, name="+b.getName()+", age="+a.getAge());} catch (ClassNotFoundException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e1){e1.printStackTrace();}}}class A implements Serializable{private String name;private int age;public String getName(){return this.name;}public int getAge(){return this.age;}public A(String name, int age){this.name=name;this.age=age;}}运行结果:创建一个对象a, name=Joyce, age=22从文中读出对象, name=Joyce, age=22
transient关键字
java中,关键字transient是用来指明不被序列化的对象(该对象关联的其他引用,也将不再被纳入对象图搜索的范围)。
比如说上面的那个代码稍作修改:
/** * 实现把一个对象写入文件,并且从这个文件恢复这个对象 * @author jin */public class Test1 {public static void main(String[] args) {A a=new A("Joyce", 22);a.b=new B();System.out.println("创建一个对象a, name="+a.getName()+", age="+a.getAge());System.out.println("a.b.x="+a.b.x);File file=new File("object.odt");try {FileOutputStream fos=new FileOutputStream(file);ObjectOutputStream oos=new ObjectOutputStream(fos);oos.writeObject(a);} catch (FileNotFoundException e) {e.printStackTrace();}catch(IOException e1){e1.printStackTrace();}try {FileInputStream fis=new FileInputStream(file);ObjectInputStream ois=new ObjectInputStream(fis);A o=(A)ois.readObject();System.out.println("从文中读出对象, name="+o.getName()+", age="+o.getAge());System.out.println("o.b.x="+o.b.x);//注释掉} catch (ClassNotFoundException e) {e.printStackTrace();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e1){e1.printStackTrace();}}}class A implements Serializable{private String name;private int age;B b;//// transient B b;public String getName(){return this.name;}public int getAge(){return this.age;}public B getB(){return this.b;}public A(String name, int age){this.name=name;this.age=age;}}class B {int x=4;}
会报错(抛出NotSerializableException异常),按照注释修改后就不会;
注意:假如在Bb;前添加了关键字transient那么从字节流中读取对象时就没有B类对象b了。
自定义序列化/反序列化
为什么需要自定义序列化/反序列化?对敏感数据进行保护
序列化机制中其实隐藏了两个私有方法writeObject()和readObject()。借助这两个方法,我们可以自己定制序列化和反序列化的方式。
对可序列化的对象执行序列化或反序列化操作时,会自动调用这两个方法。(换言之,执行public修饰的writeObject()或readObject()方法时,会自动调用对应的私有writeObject()和readObject()方法)
待续……
反序列化和new创造对象
产生的对象状态不同。New是造出初始化的对象;反序列化是恢复对象的原有状态,不会自动调用相关构造函数。
反序列化会触发相关对象图中涉及对象的构造。
序列化中的Static属性
静态属性即使未被transient关键字修饰,也不会被序列化。
- JAVA的对象序列化
- JAVA的对象序列化
- java的对象序列化
- Java对象的序列化
- Java 的对象序列化
- Java对象的序列化
- Java对象的序列化
- Java对象的序列化
- Java:对象的序列化
- Java对象的序列化
- Java对象的序列化
- Java对象的序列化
- Java对象的序列化
- java对象的序列化
- JAVA对象的序列化
- Java--对象的序列化
- Java的对象序列化
- Java 对象的序列化
- 模拟相位解调
- linux中断流程详解
- 很容易的制作双色表格
- java 反射例子
- CodeSmith生成实体类模板
- Java对象的序列化
- ACM题几个错误原因(持续更新)
- socket 、webservices、Json的区别
- 360黑匣子之谜——奇虎360“癌”性基因大揭秘
- dll的弱引用和强引用
- 算法 shell排序法 - 改良的插入排序
- 使思维导图的清晰度更高
- 华为的技术超越之路:研发费用逼近爱立信
- 设计模式总结