php 序列化 java_JAVA之序列化

1、问题:

如果想往一个文件中写入一个对象,发现字节流,字符流都不能满足要求, 如何向一个文件中写入对象?

使用字节字符流,都必须要将对象转为字节/字符,再写到文件中,可以字节字符流没有将对象转为字节的方法,这要如何做?

2、序列化与反序列化

Java序列化:将对象转为字节的过程,这正好符合我的需求。

Java反序列化:将字节恢复为对象的过程

这满足我们想文件中写对象,和读取对象

3、序列化和反序列化的使用场景a、将对象写道硬盘中;

b、网络间传输当在网络上传送文本,音频,视频等,都是转化为二进制序列传送,我们要在网络上传送对象,就必须使用序列化和反序列化,满足数据的发送和接收。

###4、序列化和反序列化的好处

一、实现数据的持久化,通过序列化将数据永久的保存在本地的硬盘上;

二、实现远程网络通信,利用序列化,使得在网络上可以传输对象的字节序列。

5、如何实现序列化和反序列化

5.1 、实现Serializable接口

Serializable接口没有任何方法,只是提供一个标识 , 用来告诉java机制该类可以被序列化;

如果没有创建这个标识,java机制将会自动的创建一个,SerialVersionUID是根据类名, 接口名,成员方法及属性等来生成一个64位哈希字段。如果没有SerialVersionUID, 通常我们会发现,如果在序列化后,修改了类的属性, 在进行反序化,会报错,因为累的属性修改了,java机制会重新创建一个SerialVersionUID, 导致与原来的ID不一致, 反序列化失败。如果设置了实现SerialVersionUID, 保证版本的兼容性, 即使添加了属性或方法, 仍然能进行序列化和反序列化, 只是新添加的属性值为null,或不显示被删除属性的值。package com.chb.test;import java.io.Serializable;public class Student implements Serializable{

//序列化标识

private static final long serialVersionUID = 1L;

private String name;

private int age;

private String sex;

public Student() {

}

public Student(String name, int age, String sex) {

super();

this.name = name;

this.age = age;

this.sex = sex;

}

@Override

public String toString() {

return "Student{"

+"姓名:"+this.name

+"性别:"+this.sex

+"年龄"+this.age

+ "}";

}

/**setter getter 省略。。。*/

}

5.2、ObjectOutputStream与ObjectInputStream

Serializalable接口只是提供一个表示,将对象转为二进制序列,和二进制序列恢复成对象是由ObjectOutputStream和OjbectInputStream提供的两个方法:writeObject()和readObject()writeObject()public static void write(Student s1) throws Exception {

FileOutputStream fos = new FileOutputStream(filename);

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(s1);

oos.close();

}readObject()public static Student read() throws Exception {

FileInputStream fis = new FileInputStream(filename);

ObjectInputStream ois = new ObjectInputStream(fis);

Student stu = new Student(); //使用readeObject()进行反序列化

stu= (Student) ois.readObject();

ois.close(); return stu;

}

6、transient

在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。

修改上面的Student类,将sex属性使用transient修饰transient private String sex;

再进行序列化Student s1 = new Student("roase",19, "女");

write(s1);

反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。

63654f9997dceb1597d964d8cef12df9.png

6.1 defaultWriteObject和defaultReadObject()

对于上面的被transient的成员age, 如果我们想让它能够在此序列化和反序列化,要如何做:1、去掉transient的修饰

2、提供两个方法private void writeObject(ObjectOutputStream out) throws Exception{

out.defaultWriteObject();

out.writeInt(age);

}

private void readObject(ObjectInputStream in) throws Exception {

in.defaultReadObject();

age=in.readInt();

}

在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:

9ebc1ec81a94a5d3d42d2756882f7a38.png

1、问题:

如果想往一个文件中写入一个对象,发现字节流,字符流都不能满足要求, 如何向一个文件中写入对象?

使用字节字符流,都必须要将对象转为字节/字符,再写到文件中,可以字节字符流没有将对象转为字节的方法,这要如何做?

2、序列化与反序列化

Java序列化:将对象转为字节的过程,这正好符合我的需求。

Java反序列化:将字节恢复为对象的过程

这满足我们想文件中写对象,和读取对象

3、序列化和反序列化的使用场景a、将对象写道硬盘中;

b、网络间传输当在网络上传送文本,音频,视频等,都是转化为二进制序列传送,我们要在网络上传送对象,就必须使用序列化和反序列化,满足数据的发送和接收。

###4、序列化和反序列化的好处

一、实现数据的持久化,通过序列化将数据永久的保存在本地的硬盘上;

二、实现远程网络通信,利用序列化,使得在网络上可以传输对象的字节序列。

5、如何实现序列化和反序列化

5.1 、实现Serializable接口

Serializable接口没有任何方法,只是提供一个标识 , 用来告诉java机制该类可以被序列化;

如果没有创建这个标识,java机制将会自动的创建一个,SerialVersionUID是根据类名, 接口名,成员方法及属性等来生成一个64位哈希字段。如果没有SerialVersionUID, 通常我们会发现,如果在序列化后,修改了类的属性, 在进行反序化,会报错,因为累的属性修改了,java机制会重新创建一个SerialVersionUID, 导致与原来的ID不一致, 反序列化失败。如果设置了实现SerialVersionUID, 保证版本的兼容性, 即使添加了属性或方法, 仍然能进行序列化和反序列化, 只是新添加的属性值为null,或不显示被删除属性的值。package com.chb.test;import java.io.Serializable;public class Student implements Serializable{

//序列化标识

private static final long serialVersionUID = 1L;

private String name;

private int age;

private String sex;

public Student() {

}

public Student(String name, int age, String sex) {

super();

this.name = name;

this.age = age;

this.sex = sex;

}

@Override

public String toString() {

return "Student{"

+"姓名:"+this.name

+"性别:"+this.sex

+"年龄"+this.age

+ "}";

}

/**setter getter 省略。。。*/ }

5.2、ObjectOutputStream与ObjectInputStream

Serializalable接口只是提供一个表示,将对象转为二进制序列,和二进制序列恢复成对象是由ObjectOutputStream和OjbectInputStream提供的两个方法:writeObject()和readObject()writeObject()public static void write(Student s1) throws Exception {

FileOutputStream fos = new FileOutputStream(filename);

ObjectOutputStream oos = new ObjectOutputStream(fos);

oos.writeObject(s1);

oos.close();

}readObject()public static Student read() throws Exception {

FileInputStream fis = new FileInputStream(filename);

ObjectInputStream ois = new ObjectInputStream(fis);

Student stu = new Student(); //使用readeObject()进行反序列化

stu= (Student) ois.readObject();

ois.close(); return stu;

}

6、transient

在某种场合,我们对某些敏感字段不要进行序列化,或者类的引用类型的成员不能够进行序列化, 这是我们需要使用transient来修饰这些成员, 以避免它们被序列化。如:银行账户对象,不希望对账户金额进行序列化。

修改上面的Student类,将sex属性使用transient修饰transient private String sex;

再进行序列化Student s1 = new Student("roase",19, "女");

write(s1);

反序列化, 读取的对象发现:sex为null,说明被transient修饰的属性不会被序列化。

63654f9997dceb1597d964d8cef12df9.png

6.1 defaultWriteObject和defaultReadObject()

对于上面的被transient的成员age, 如果我们想让它能够在此序列化和反序列化,要如何做:1、去掉transient的修饰

2、提供两个方法private void writeObject(ObjectOutputStream out) throws Exception{

out.defaultWriteObject();

out.writeInt(age);

}

private void readObject(ObjectInputStream in) throws Exception {

in.defaultReadObject();

age=in.readInt();

}

在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行read()应用程序,则又会有如下输出:

9ebc1ec81a94a5d3d42d2756882f7a38.png

以上就是JAVA之序列化的内容,更多相关内容请关注PHP中文网(www.php.cn)!

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值