您的位置:首页 > 编程语言 > Java开发

Java对象表示方式:序列化、反序列化和transient关键字的作用

2019-03-21 15:41 148 查看
版权声明:Copyright © 2019-2099 沧海桑田 https://blog.csdn.net/weixin_38270240/article/details/88706985

【转】Java对象表示方式:序列化、反序列化和transient关键字的作用
【序列化的作用】
在开发程序过程中,经常需要将对象的信息保存到磁盘中,便于以后检索。一种做法是,用输出流逐一对对象的属性信息进行写出,这样做工作量巨大,而且容易出错,如果有大量对象要去保存数据,这样做是不现实的。序列化(又称串行化)解决了这个问题。
序列化就是将对象的状态存储到特定存储介质(通常是指文件)中的过程,将对象状态转为可保持或传输格式的过程。具体而言,在序列化过程中,会将对象的成员包括其类名,转为字节流,再把字节流写入到数据流,存储到存储介质(通常是指文件)中。
使用序列化的意义在于,将java对象序列化后,可以将其转换为字节序列,这些字节序列可以被保存在磁盘上,也可以借助网络进行传输。同时,序列化后的对象保存的是二进制状态,这样实现了平台无关性,即可以在不同操作系统中传播,通过反序列化后得到对象,而不会出现数据因平台问题显示异常。
【反序列化的作用】
序列化是将对象的状态信息保存到存储介质中,反序列化则是从特定存储介质中将数据重新构建对象的过程。通过反序列化,可以将存储在文件上的对象信息读取,然后重新整合构建为对象。这样就不需要将文件上的信息一一读取、分析后再组织为对象这样繁琐的操作了。
【使用序列化保存、反序列化读取对象信息的前提】
前提是,目标对象所在的类实现Serializable接口。只有实现了java.io.Serializable接口的类的对象,才可以被序列化。JDK类库中的String类、包装类、Date类等,都实现了序列化。程序员自己创建的类需自己实现序列化接口,实际上,Serializable接口中没有任何内容,实现该接口只需要Add default serial version ID,点击类名完成,会自动创建一个private static final long serialVersionUID。
语法:public class 目标类 implements java.io.Serializable{}
【使用序列化保存对象信息的步骤】
1.创建输出流ObjectOutputStream对象oos,指向目标文件,该文件用于存储已序列化了的目标对象
语法:ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(“目标文件路径”))//参数File file
2.通过输出流ObjectOutputStream对象oos的writeObject(obj)方法向目标文件写入已序列化了的目标对象,传入已序列化了的目标对象名为实参
语法:oos.writeObject(已序列化了的目标对象)
【使用反序列化获取对象信息的步骤】
1.创建输入流ObjectInputStream对象ois,指向目标文件,该文件存储了目标对象的信息
语法:ObjectInputStream ois=new ObjectInputStream(new FileOutputStream(“目标文件路径”))//参数File file
2.通过输出流ObjectInputStream对象ois的readObject()方法从目标文件读出目标对象,读出的结果是一个Object对象,需要强转为目标对象
语法:目标类 对象引用变量=(目标类)ois.readObject()
3.通过对象引用变量访问对象成员

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializableInputOutputObjectData {

/**
* 使用序列化写和反序列化读对象内容
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.使用序列化写对象至目标文件
//1.1创建输出流ObjectOutputStream对象oos,指向目标文件,该文件用于存储已序列化了的目标对象
FileOutputStream fos=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\object.txt",true);
ObjectOutputStream oos=new ObjectOutputStream(fos);
//1.2创建目标对象,该对象所在的类已经实现序列化
Student stu1=new Student("小明", 123);
//1.3通过oos的writeObject(obj)方法向目标文件写入目标对象,传入目标对象名为实参
oos.writeObject(stu1);
//1.4依次关闭相关输出流
System.out.println("对象序列化成功");
oos.close();
fos.close();

//2.使用反序列化从目标文件读对象
//2.1创建输入流ObjectInputStream对象ois,指向目标文件,该文件存储了目标对象的信息
FileInputStream fis=new FileInputStream("C:\\Users\\Administrator\\Desktop\\object.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
//2.2通过ois的readObject()方法从目标文件读出目标对象,读出的结果是一个Object对象,需要强转为目标对象
Student stu2=(Student) ois.readObject();
//2.3通过对象引用变量访问对象成员
System.out.println(stu2);
//2.4依次关闭相关输入流
System.out.println("对象反序列化成功");
ois.close();
fis.close();
}
}

【属性加密】
通常,对象中的所有属性都会被序列化,但是对于一些比较敏感的信息,如用户的密码,一旦序列化后,人们可以通过读取文件或拦截网络传输数据的方式,获得这些信息。因此,出于安全考虑,某些属性应该限制被序列化。解决的办法是使用transient关键字为其加密,如transient private String password.
【序列化的深度】
如果要序列化某个特定的对象,那么它的各个成员对象必须也是可序列化的。所有保存到磁盘中的对象都有一个序列号。
【序列化写入多个对象】
如果使用序列化机制向文件中写入多个对象,那么反序列化恢复对象时,必须按照写入的顺序读取
【序列化类的父类】
如果一个类可序列化,那么其父类要么是可序列化的,要么有无参构造,否则会抛出异常

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: