龙空技术网

Java基础——IO流(8)

程序员进阶之路 307

前言:

当前咱们对“java数的分解”大约比较注意,看官们都需要知道一些“java数的分解”的相关资讯。那么小编也在网上搜集了一些关于“java数的分解””的相关知识,希望你们能喜欢,各位老铁们快快来了解一下吧!

1 基本概括2 主要介绍

2.1 序列化

2.1.1 序列化和反序列化

序列化:将内存中的java对象分解成数小块,并按照顺序一块一块存储到硬盘文件中,成为对象的序列化。

反序列化:将硬盘中的对象文件,按照顺序还原到内存中,称为对象的反序列化。

想要完成对象的输入输出,还必须依靠ObjectInputStream和ObjectOutputStream;

使用对象输出流输出序列化对象的步骤,也称为序列化,而使用对象输入流读入对象的过程,也称为反序列化。

2.1.2 对象能够序列化,必须实现可序列接口Serializable

这个Serializable接口中没有任何代码,只是起到一个标志的作用。

java中的接口分两种:普通接口 和 标志接口,期中标志接口中没有任何代码。

Serializable这个标志接口是给JVM看的,虚拟机看到这个接口之后,会为实现类自动生成一个序列化版本号。

2.1.3 序列化版本号有什么用?

序列化版本号是让类实现了Serializable接口后,标志着这个类此时的版本。

若以后修改了类中代码,版本号又会改变,以前序列化的文件无法反序列化还原。

2.1.4 JVM是如何区分两个可序列化类的类型是否一致

第一步:先比较两个类的完整类名,就是前面包括了包名。如果类名不一致,那就是两个不同的类型。

第二步:如果类名一致,再比较两个类的序列化版本号是否一致。

2.1.5 实现序列化机制的对象对应的类的要求

要求类要实现Serializable接口

同样要求类的所有属性也必须实现Serializable接口

要求给类提供一个序列版本号:private static final long serialVersionUID

属性声明为static 或transient的,不可以实现序列化

2.1.6 什么是对象序列化?为什么要实现对象的序列化?

序列化是指将对象的状态信息转换为可以存储或传输的形式(2进制数据)的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

序列化的目的:

1)永久的保存对象,保存对象的字节序列到本地文件中;

2)通过序列化对象在网络中传递对象;

3)通过序列化对象在进程间传递对象。

2.1.7 serialVersionUID

在对象进行序列化或者反序列化操作的时候,要考虑JDK版本的问题,如果序列化的JDK版本和反序列化的JDK版本不统一则就可能造成异常,所以在序列化操作中引入了一个serialVersionUID的常量,可以通过此常量来验证版本的一致性,在进行反序列化时,JVM会将传过来的字节流中的serialVersionUID与本地相应实体的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就抛出不一致的异常。

2.1.8 到底序列化了哪些东西呢?

所有的对象拥有各自的属性值,但是所有的方法都是公共的,所以序列化对象的时候实际上序列化的就是属性。

2.1.9 Externalzable接口

使用Serilizable 接口可以方便的序列化一个对象,但是在序列化操作中也提供了另外一种序列化机制

被Serialization接口声明的类其对象可以被序列化,如果现在用户希望可以自己制定序列化的内容,则可以让一个类实现Externalizable接口,此接口定义如下。

public interface Externalization extends Serializable{

public void writeExternal(ObjectOutput out) throws IOException;

public void writeExternal(ObjectIntput in) throws IOException,ClassNotFoundException;

}

方法:

写入:void writeExternal(ObjectOutput out) throws IOException

读取:void readExternal(ObjectInput in)throws IOException,ClassNotFoundException

2.1.10 序列化的步骤

序列化的一般步骤可以分为5步:

1.声明对象输出流

2.声明文件输出流,并实例化

3.用文件输出流对象实例化对象输出流

4.调用对象输出流的writeObject函数保存对象

5.关闭对象输出流

反序列化步骤:

1.声明对象输入流

2.声明文件输入流

3.用文件输入流对象实例化对象输入流

4.调用对象输入流的readObject函数读取对象,打印读取到的对象内容

5.关闭对象输入流

2.1.11 Externalizable和Serializable接口实现序列化的区别

Externalizable相对于Serializable来说实现复杂,执行效率高,保存信息空间减少。

transient关键字:

在序列化操作的时候,如果某个属性不希望被序列化下来,则可以直接使用transient 关键字声明。

3 简单用例

3.1 写入对象

@Testpublic void IOTest1() throws Exception{    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\test.txt"));    oos.writeInt(10);    oos.writeObject(new String("测试"));    oos.close();}

3.2 读取对象

@Testpublic void IOTest2() throws Exception{    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\test.txt"));    oos.writeInt(10);    oos.writeObject(new String("测试"));    oos.close();}

3.3写入一个Student对象

@Testpublic void IOTest3() throws Exception{    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\test.txt"));    oos.writeObject(new Student("测试",18));    oos.close();}

3.4读取对象

 @Testpublic void IOTest4() throws Exception{    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\test.txt"));    Student stu = (Student) ois.readObject();    System.out.println(stu);    ois.close();}

标签: #java数的分解