Java序列化带参构造函数_Java学习笔记(十三)--序列化、反序列化与无参构造函数...

概念

序列化:将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制允许把内存中的Java对象转换成平台无关的二进制,从而可以持久的保存在磁盘上,也可以在网络中传输。

反序列化:程序一旦获得了序列化的对象,则这种二进制流都可以恢复成原来的

如何实现序列化

1.Serializable

要序列化的对象,实现该接口,无需重写任何方法

2.Externalizable

要序列化的对象实现该接口,并且需要实现writeExternal和readExternal方法

简单对象的序列化

1.单一的对象序列化

创建一个Person类

public class Person implements Serializable{

private String id;

public Person(String id) {

System.out.println("youcacn");

this.id = id;

}

@Override

public String toString() {

return "Person{" +

"id='" + id + '\'' +

'}';

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

}

注意:1.Person类实现了Serializable接口

2.该实体类没有提供无参构造函数

写一个测试类,测试一下序列化与反序列化

try {

//序列化

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("2.txt"));

Person person = new Person("111");

objectOutputStream.writeObject(person);

//反序列化

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("2.txt"));

Person person1 = (Person) objectInputStream.readObject();

System.out.println(person1.toString());

} catch (Exception e) {

e.printStackTrace();

}

执行结果

4118a1725d5254777c3c68528fae9aac.png

Person类去掉实现序列化接口(即,将public class Person implements Serializable修改为public class Person),重新执行

185c17de9ad20ae0cd77f77eb1892189.png

结论:简单类型(无继承关系)对象序列化时必须实现序列化接口,有无无参构造函数都key

2.存在继承关系,但并无引用关系的对象序列化

创建Student类,继承Person类

public class Student extends Person implements Serializable{

private int no;

@Override

public String toString() {

return "Student{" +

"no=" + no +

'}';

}

public Student(String id ,int no) {

super(id);

this.no = no;

}

public int getNo() {

return no;

}

public void setNo(int no) {

this.no = no;

}

}

Person类对象既没实现序列化接口,又没有提供无参构造函数

public class Person{

private String id;

// public Person() {

// }

public Person(String id) {

System.out.println("youcacn");

this.id = id;

}

@Override

public String toString() {

return "Person{" +

"id='" + id + '\'' +

'}';

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

}

执行序列化与反序列化

e5f0a018a205a46501e1229d989c3040.png

另Person对象实现序列化接口,再次执行,结果成功

public class Person implements Serializable{

private String id;

// public Person() {

// }

public Person(String id) {

System.out.println("youcacn");

this.id = id;

}

@Override

public String toString() {

return "Person{" +

"id='" + id + '\'' +

'}';

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

}

不实现序列化接口,提供无参构造函数,执行结果成功

public class Person {

private String id;

public Person() {

}

public Person(String id) {

System.out.println("youcacn");

this.id = id;

}

@Override

public String toString() {

return "Person{" +

"id='" + id + '\'' +

'}';

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

}

结论:存在继承关系时,若想序列化子类对象,一并序列化父类对象,则负责类型必须实现序列化接口或者提供无参构造函数

对象引用的序列化

Student类继承Person类,并有对象引用关系

public class Student extends Person implements Serializable {

private int no;

private Person person;

public Person getPerson() {

return person;

}

public void setPerson(Person person) {

this.person = person;

}

@Override

public String toString() {

return "Student{" +

"no=" + no +

'}';

}

public Student(String id, int no) {

super(id);

this.no = no;

}

public int getNo() {

return no;

}

public void setNo(int no) {

this.no = no;

}

}

一个demo序列化Student实例与反序列化Student实例

try {

//序列化

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("2.txt"));

Person person = new Person("111");

Student stuB = new Student("B", 163);

stuB.setPerson(person);

objectOutputStream.writeObject(stuB);

//反序列化

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("2.txt"));

Student student = (Student) objectInputStream.readObject();

System.out.println(student.getPerson());

} catch (Exception e) {

e.printStackTrace();

}

Person类不实现序列化接口,也不提供无参构造函数,执行结果如下:

bfb4d485f2cd82c5fd7137fa88279f79.png

Person类不实现序列化接口,提供无参构造函数,执行结果如下:

8ae4ad585d56c53acba90cc2f7f1dca3.png

Person类实现序列化接口,但不提供无参构造函数,执行结果如下:

6178c8cc5865147290e6fb5b213fbca5.png

结论

单一对象,无继承关系:若想实现序列化与反序列化,则必须实现序列化接口,否则报异常:NotSerializableException

对象间有继承关系,但无引用关系,若想实现序列化与反序列化,则父类必须实现序列化接口或提供无参构造函数,否则报invalidClassException

对象间有继承关系,并且有引用关系,若想实现序列化与反序列化,则父类必须实现序列化接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值