- 概述
- 序列化方式
- Serializable
- 序列化源码
- ObjectOutputStream
我们的对象并不只是存在内存中,还需要传输网络,或者保存起来下次再加载出来用,所以需要Java序列化技术。序列化将对象"转换"成字节序列,方便持久化存储到磁盘,或者网络传输。因为对象有生命周期,依赖JVM,一旦生命周期结束,对象就被垃圾回收或者脱离虚拟机(网络传输),对象就不存在了,所有对于数据传输对象序列化很有必要。
- 实现Serializable接口
- Externalizable接口
一个对象想要序列化就必须实现Serializable接口,这是一个标记接口,只有实现了它ObjectOutputStream才能通过writeObject0()方法把对象转成普通对象流。
- 序列化对象的所有属性(private属性、其引用的对象,static修饰除外)都可以被序列化和反序列化来保存、传递。不想序列化的字段可以使用transient修饰。
- 使用transient关键字阻止序列化简单方便,但被它修饰的属性被完全隔离在序列化机制之外,导致了在反序列化时无法获取该属性的值,而通过在需要序列化的对象的类里加入writeObject()方法与readObject()方法可以控制如何序列化各属性,甚至完全不序列化某些属性或者加密序列化某些属性。
InfoObj定义
public class InfoObj implements Serializable {
private Integer number;
private String address;
private Date date;
//private String name;
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "InfoObj{" +
"number=" + number +
", address='" + address + ''' +
", date=" + date +
'}';
}
}
序列化
public static void main(String[] args) throws IOException, ClassNotFoundException {
InfoObj info = new InfoObj();
info.setNumber(119064233);
info.setAddress("马鞍山");
info.setDate(new Date());
ObjectOutputStream objectOutputStream =
new ObjectOutputStream( new FileOutputStream( new File("InfoObj.txt") ) );
objectOutputStream.writeObject( info);
objectOutputStream.close();
System.out.println("序列化成功!已经生成InfoObj.txt文件");
System.out.println("==============================================");*/
deserialize();
}
反序列化
public static void deserialize() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream =
new ObjectInputStream( new FileInputStream( new File("InfoObj.txt") ) );
InfoObj info = (InfoObj) objectInputStream.readObject();
objectInputStream.close();
System.out.println("反序列化结果为:");
System.out.println( info );
}
static和transient修饰
public class InfoObj implements Serializable {
...
//属性增加一个静态name
public static String name ="wellim";
//transient属性passwd
private transient String passwd;
...
}
运行序列化
InfoObj info = new InfoObj();
info.setNumber(119064233);
info.setAddress("马鞍山");
info.setDate(new Date());
info.setPasswd("w4567");
反序列化
static静态变量在class对象上,所以序列化普通对象没有该属性。
序列化源码 ObjectOutputStream继承了OutputStream,实现了ObjectOutput,和ObjectStreamConstants。主要继承了输出流基本操作,和对象输出的读写方法、对象流的常量。
public class ObjectOutputStream
extends OutputStream implements ObjectOutput, ObjectStreamConstants
序列化对象信息分为三个部分:
- 序列化头信息:用于描述序列化协议的魔数和版本。
- 类描述的信息:用于描述序列化类的名称,属性和父类的名称、属性。
- 属性域的值的描述:用于记录当前类中属性的值
- 类描述规则是:标志(TC_OBJECT = 0x73)
- 新类的描述(TC_CLASSDESC = 0x72)
public interface ObjectStreamConstants {
static final short STREAM_MAGIC = (short)0xaced;
static final short STREAM_VERSION = 5;
static final byte TC_base = 0x70;
static final byte TC_NULL = (byte)0x70;
static final byte TC_REFERENCE = (byte)0x71;
static final byte TC_CLASSDESC = (byte)0x72;
static final byte TC_OBJECT = (byte)0x73;
static final byte TC_STRING = (byte)0x74;
static final byte TC_ARRAY = (byte)0x75;
static final byte TC_CLASS = (byte)0x76;
static final byte TC_BLOCKDATA = (byte)0x77;
static final byte TC_ENDBLOCKDATA = (byte)0x78;
static final byte TC_RESET = (byte)0x79;
static final byte TC_BLOCKDATALONG= (byte)0x7A;
static final byte TC_EXCEPTION = (byte)0x7B;
static final byte TC_LonGSTRING = (byte)0x7C;
static final byte TC_PROXYCLASSDESC = (byte)0x7D;
static final byte TC_ENUM = (byte)0x7E;
static final byte TC_MAX = (byte)0x7E;
static final int baseWireHandle = 0x7e0000;
static final byte SC_WRITE_METHOD = 0x01;
static final byte SC_BLOCK_DATA = 0x08;
static final byte SC_SERIALIZABLE = 0x02;
static final byte SC_EXTERNALIZABLE = 0x04;
static final byte SC_ENUM = 0x10;
static final SerializablePermission SUBSTITUTION_PERMISSION =
new SerializablePermission("enableSubstitution");
static final SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new SerializablePermission("enableSubclassImplementation");
static final SerializablePermission SERIAL_FILTER_PERMISSION =
new SerializablePermission("serialFilter");
public static final int PROTOCOL_VERSION_1 = 1;
public static final int PROTOCOL_VERSION_2 = 2;
}



