18、Java入门—Java IO流之对象的序列化和反序列化

1.对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化
2.序列化流(OjectOutputStream)是过滤流----writeObject
反序列化流(ObjectInputStream)----readObject
3.序列化借口(Serializable)
对象必须实现序列化借口,才能进行序列化,否则将出现异常
这个借口,没有任何方法,只是一个标准
对象实体类的序列化与反序列化
public static void main(String[] args) throws IOException, Exception {
String file = "F:/IO流/序列化/test.txt";
// 1.对象的序列化
/*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
file));
Student stu = new Student("10011", "张三 ", 20);
oos.writeObject(stu);
oos.flush();
oos.close();*/


// 2.反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Student stu2 = (Student) ois.readObject();
System.out.println(stu2);
ois.close();


}

1.transient该元素不会进行jvm默认的序列化,也可以自己完成这个元素的序列化
注意:
(1)在以后的网络编程中,如果有某些元素不需要传输,那就可以用transient修饰,来节省流量;对有效元素序列化,提高性能。
(2)可以使用writeObject自己完成这个元素的序列化。ArrayList就是用了此方法进行了优化操作。ArrayList最核心的容器Object[] elementData使用了transient修饰,但是在writeObject自己实现对elementData数组的序列化。只对数组中有效元素进行序列化。readObject与之类似。
(3)java.io.ObjectOutputStream.defaultWriteObject();
// 把jvm能默认序列化的元素进行序列化操作
java.io.ObjectOutputStream.writeInt(age);// 自己完成序列化
(4)
java.io.ObjectOutputStream.defaultReadObject();// 把jvm能默认反序列化的元素进行反序列化
this.age = java.io.ObjectOutputStream.readInt(); // 自己完成age的反序列化操作

private void writeObject(java.io.ObjectOutputStream s)
       throws java.io.IOException{
s.defaultWriteObject();//把jvm能默认序列化的元素进行序列化操作
s.writeInt(stuage);//自己完成stuage的序列化
}
private void readObject(java.io.ObjectInputStream s)
       throws java.io.IOException, ClassNotFoundException{
 s.defaultReadObject();//把jvm能默认反序列化的元素进行反序列化操作
 this.stuage = s.readInt();//自己完成stuage的反序列化操作
}


序列化时父类构造函数:
1.子类在反序列化时,父类实现了序列化接口,就不会递归调用其构造函数
  而父类实现了serializable接口,子类继承就可序列化
2.子类在反序列化时,父类没有实现序列化接口,则会递归调用其构造函数
  父类未实现serializable接口,子类自行实现可序列化
结论:当父类实现了serializable接口,子类可以被序列化,当对子类对象进行反序列化操作时,如果其父类没有实现序列化接口,则其父类的构造函数会被调用,反之父类的构造函数不会被调用。归结为有序列化接口的构造函数不会被调用


验证类
/*
 * 一个类实现了序列化接口,那么其子类都可以进行序列化。 对子类对象进行反序列化操作时,如果其父类没有实现序列化接口 ,那么其父类的构造函数会被调用。
 */
class Foo implements Serializable {
public Foo() {
System.out.println("foo...");
}
}


class Foo1 extends Foo {
public Foo1() {
System.out.println("foo1...");
}
}


class Foo2 extends Foo1 {
public Foo2() {
System.out.println("foo2...");
}
}


class Bar {
public Bar() {
System.out.println("Bar...");
}
}


class Bar1 extends Bar implements Serializable {
public Bar1() {
System.out.println("bar1...");
}
}


class Bar2 extends Bar1 {
public Bar2() {
System.out.println("Bar2...");
}
}


序列化主函数
public static void main(String[] args) throws IOException, Exception {
/*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"F:/IO流/序列化/test2.txt"));
Foo2 foo2 = new Foo2();
oos.writeObject(foo2);
oos.flush();
oos.close();*/


// 反序列化时是否递归调用父类函数
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"F:/IO流/序列化/test2.txt"));
Foo2 foo2 = (Foo2) ois.readObject();
System.out.println(foo2);
ois.close();


/*ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"F:/IO流/序列化/test2.txt"));
Bar2 bar2 = new Bar2();
oos.writeObject(bar2);
oos.flush();
oos.close();*/


/*ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"F:/IO流/序列化/test2.txt"));
Bar2 bar2 = (Bar2) ois.readObject();
System.out.println(bar2);
ois.close();*/
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值