java核心学习(十七) IO框架---对象序列化
Posted The_shy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java核心学习(十七) IO框架---对象序列化相关的知识,希望对你有一定的参考价值。
一、使用对象流实现序列化。
先定义一个可序列化的对象
package com.shy.IO; import java.io.Serializable; public class Person implements Serializable{ public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } private int age; private String name; public Person(String name , int age){ this.age = age; this.name = name; } }
然后将Persen类的实例使用对象流序列化
package com.shy.IO;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class WriteObject {
public static void main(String[] args) {
try (
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("object.txt"));
) {
Person person = new Person("yuyu", 22);
outputStream.writeObject(person);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
最后再反序列化
package com.shy.IO;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ReadObject {
public static void main(String[] args) {
try (
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("object.txt"))
) {
Person person = (Person) inputStream.readObject();
System.out.println(person.getName()+"的年龄为"+person.getAge());
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
}
}
}
由上面代码可以看出,反序列化时必须进行downcasting,而且反序列化机制度区的仅仅是java对象的数据,而且没有使用对象构造器,这表明反序列化机制无需通过构造起来初始化java对象。
二、java对象序列化算法内容简介
1、所有保存到磁盘中的对象都有一个序列化编号。
2、当程序试图序列化一个对象时,程序会先检查该对象是否被序列化过,只有该对象从未(在本次虚拟机中)被序列化过,系统才会将对象转化为字节序列并输出。
3、如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是再次重新序列化该对象。
三、自定义序列化
对实现了Serializable接口的对象,可使用下列三种方式来自定义序列化与反序列化。
第一种方式,若在实例成员变量前面使用transient关键字修饰,可以指定java序列化时无需理会该实例变量;
第二种方式,在需要序列化的类中提供如下特殊签名的方法,在这些方法中分别对java对象的成员变量用out.writeObject()方法进行存取
private void writeObject(java.io.ObjectOutputStream out)throws IOException; private void readObject(java.io.ObjectInputStream in)throws IOException,ClassNotFoundException; private void readObjectNoData()throws ObjectStreamException;
第三种方式,在序列化时将该对象替换成其他对象,此时应该为序列化提供如下方法,序列化机制会序列化该方法返回的对象。
private Object writeReplace() throws ObjectStreamException;
通过上面介绍,可以知道java序列化机制在将对象序列化写入文件之前,先调用被序列化对象的writeObject方法,然后再调用writeReplace方法,相对应的,在从文件中读取对象时的最后,会调用readObject方法,之后再调用readResolve方法,该方法和writeReplace方法很像,可以将源序列化对象转换为另一个对象来返回,可以用来实现白虎幸福之整个对象。
四、另一种序列化机制,实现Externalizable接口
与serializable这种声明式接口不同,Externalizable接口里面定义了两个方法writeExternal() and readExternal()两个方法,这两个方法除了名字与writeObject和readObject不同外其他都相同,用处就是强制自定义序列化。
五、序列化的范围
对象的类名和实例变量都会被序列化,方法、类变量,transient变量都不会被序列化。
六、serialVersionUID
在定义序列化对象时最好手动定义序列化对象的版本,也就是在序列化对象中定义一个静态成员变量,private static fianl long serialVersionUID = 512L;用于保证class文件改变之后还可以正确反序列化。
以上是关于java核心学习(十七) IO框架---对象序列化的主要内容,如果未能解决你的问题,请参考以下文章
java核心学习(十八) javaNIO框架---“块”模型的IO
Java 学习笔记 - IO篇:对象流 ObjectInputStreamObjectOutputStream