Java对象序列化(Object Serialization)
来源:互联网 发布:加入淘宝充值平台赚钱 编辑:程序博客网 时间:2024/05/01 11:32
Java1.1中实现了Serializable接口的对象都可被转换成一系列字节,并可完全恢复成原状。Java中的两个特性运用了对象序列化:远程调用方法(RMI),Java Beans
要序列化一个对象(其类已实现Serializable接口),需要创建一些OutputStream对象,将其封装到ObjectOutputStream对象中,调用writeObject()方法即可将序列化的对象发生到OutputStream中,比如文件、String、网络等。当要恢复对象时,只需将InputStream封装到ObjectInputStream对象中,调用readObject()方法即可,当然此时必须上溯造型到原始类型。
1. Serializable接口实例
package com.test;import java.io.*;class Data implements Serializable {private int i;Data(int x) { i = x; }public String toString() {return Integer.toString(i);}}public class Serial implements Serializable {//Generate random intprivate static int r() {return (int)(Math.random() * 10);}private Data[] d = {new Data(r()), new Data(r()), new Data(r())};private Serial next;private char c;Serial(int i, char x) {System.out.println(" Serial constructor: " + i);c = x;if (--i >0)next = new Serial(i, (char)(x+1));}Serial() {System.out.println("Default constructor");}public String toString() {String s = ":" + c + "(";for (int i = 0; i < d.length; i++) {s += d[i].toString();}s += ")";if (next != null)s += next.toString();return s;}public static void main(String[] args) {Serial w = new Serial(6, 'e');System.out.println("w = " + w);try {//write the serialized objects to fileObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("serial.out"));out.writeObject("Serial test");out.writeObject(w);out.close(); //will also flush output//read and restore serialized objects from fileObjectInputStream in = new ObjectInputStream(new FileInputStream("serial.out"));String s = (String)in.readObject();Serial w2 = (Serial)in.readObject();System.out.println(s + ", w2 = " + w2);} catch (Exception e) {e.printStackTrace();}try {//write the serialized objects to memoryByteArrayOutputStream bout = new ByteArrayOutputStream();ObjectOutputStream out = new ObjectOutputStream(bout);out.writeObject("Serial test");out.writeObject(w);out.flush();//read and restore from memoryObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bout.toByteArray()));String s = (String)in.readObject();Serial w3 = (Serial)in.readObject();System.out.println(s + ", w3 = " + w3);} catch (Exception e) {e.printStackTrace();}}}在读取并恢复Serializable对象的时候不会允许构建器,而且对象序列化没有用到IO系统的Reader和Writer,而是使用Java1.0的InputStream和OutputStream体系。
2. Externalizable接口
实现了Serializable接口的对象序列化时,默认会将类中所有字段包含进去。但是有时涉及安全问题,有些字段我们不想被序列化,这时可使用Externalizable接口控制序列化过程。Externalizable接口扩展了Serializable接口,并添加了两个方法writeExternal()和readExternal()。在序列化和恢复的过程中会自动调用这两个方法,我们可以通过改写他们控制序列化和恢复过程。
实例1,实现Externalizable接口的对象在恢复是会调用类的默认构建器,注意Blip2的默认构建器不是public的,这样会导致调用权限不够而产生异常
package com.test;import java.io.*;import java.util.*;class Blip1 implements Externalizable {public Blip1() {System.out.println("Blip1 constructor");}public void writeExternal(ObjectOutput out) throws IOException {System.out.println("Blip1.writeExternal");}public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {System.out.println("Blip1.readExternal");}}class Blip2 implements Externalizable {Blip2() {System.out.println("Blip2 constructor");}public void writeExternal(ObjectOutput out) throws IOException {System.out.println("Blip2.writeExternal");}public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {System.out.println("Blip2.readExternal");}}public class External {public static void main(String[] args) {System.out.println("Constructing objects: ");Blip1 b1 = new Blip1();Blip2 b2 = new Blip2();try {//write serialzed objectsObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Blips.out"));System.out.println("Saving objects: ");out.writeObject(b1);out.writeObject(b2);out.close();//read and restore objectsObjectInputStream in = new ObjectInputStream(new FileInputStream("Blips.out"));System.out.println("Recovering b1:");b1 = (Blip1)in.readObject();//following will throw exception //as Blip2's default constructor is not public//b2 = (Blip2)in.readObject();} catch (Exception e) {e.printStackTrace();}}}
实例2,在readExternal和writeExternal中控制序列化过程
package com.test;import java.io.*;import java.util.*;public class External2 implements Externalizable {int i;String s; //not initializepublic External2() {System.out.println("External2 constructor");}public External2(String x, int a) {System.out.println("External2(String x, int a)");s = x;i = a;}public String toString() { return s + i; }public void writeExternal(ObjectOutput out) throws IOException {System.out.println("External2.writeExternal");//write the fields you want to serialize//you can only serialize some fieldsout.writeObject(s);out.writeObject(i);}public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {System.out.println("External2.readExternal");//Restore the fields that are serializeds = (String)in.readObject();i = in.readInt();}public static void main(String[] args) {System.out.println("Constructing objects: ");External2 e2 = new External2("A string", 42);System.out.println(e2.toString());try {ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("external2.out"));System.out.println("Saving object: ");out.writeObject(e2);out.close();//restore objectObjectInputStream in = new ObjectInputStream(new FileInputStream("external2.out"));System.out.println("Recovering e2:");e2 = (External2)in.readObject();System.out.println(e2.toString());} catch (Exception e) {e.printStackTrace();}}}
3. transient关键字
实现Serializable接口的类序列化时默认所有fields都会被序列化,transient关键字可以关闭fields的序列化。设置成transient的字段不参与序列化,恢复时简单的设置成默认值,如int 0, 对象句柄 null。
4. writeObject()和readObject()方法代替Externalizable
实现Serializable接口,并添加writeObject()和readObject()方法也可以控制序列化过程。但是这两个方法在类中都被定义成private,按理说外部类是不能调用的,这里序列化过程绕过了检查,这种绕过检查的机制我们普通用户是不可能接触到的。。。
private void writeObject(ObjectOutputStream stream) throws IOException;private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException;
实例:
//: SerialCtl.java //Controlling serialization by adding your own //writeObject() and readObject() methods. import java.io.*; public class SerialCtl implements Serializable { String a; transient String b; public SerialCtl(String aa, String bb) { a = "Not Transient: " + aa; b = "Transient: " + bb; } public String toString() { return a + "\n" + b; } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); stream.writeObject(b); } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); b = (String)stream.readObject(); } public static void main(String[] args) { SerialCtl sc = new SerialCtl("Test1", "Test2"); System.out.println("Before:\n" + sc); ByteArrayOutputStream buf = new ByteArrayOutputStream(); try { ObjectOutputStream o = new ObjectOutputStream(buf); o.writeObject(sc); // Now get it back: ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( buf.toByteArray())); SerialCtl sc2 = (SerialCtl)in.readObject(); System.out.println("After:\n" + sc2); } catch(Exception e) { e.printStackTrace(); } } } ///:~
- Java对象序列化(Object Serialization)
- Java对象序列化 Object Serialization
- android-java对象序列化Object serialization
- 对象序列化(Object Serialization)
- Java源码——对象序列化(对象的存储及读取)(Object Serialization)
- java中对象序列化(Serialization)的注意事项
- C++ / QT 对象序列化(Object Serialization)的实现
- 浅析Java Object Serialization与 Hadoop 序列化
- 浅析Java Object Serialization与 Hadoop 序列化
- 序列化(Serialization)一个对象
- Java Serialization 序列化
- JHTP小结_第十五章_文件、流和对象序列化(Files, Streams, and Object Serialization)
- JHTP自测题_第十五章_文件、流和对象序列化(Files, Streams, and Object Serialization)
- Java 网络编程 之 传输对象 Serialization 序列化
- java serialization/deserialization (序列化对象自描述)
- 序列化(serialization)
- 序列化(serialization)
- “序列化”(Serialization)
- 一路上有你,苦一点也愿意
- 【cocos2dx 3.2】一个都不能死8 修改与发布
- POJ 2828 Buy Tickets(线段树)
- C语言总结
- 第9周项目6-穷举法解决组合问题之委派任务
- Java对象序列化(Object Serialization)
- 【笨木头Lua专栏】基础补充05:迭代器番外篇
- 判断元素重复
- 使用jni技术进行android应用签名信息核查及敏感信息保护
- Permutation Sequence
- uva 10167 Birthday Cake 枚举
- Machine Learning Foundations(机器学习基石) By Hsuan-Tien Lin (林轩田) week1 笔记
- Leetcode--Valid Number
- 关于信号与系统