序列化概述
将Java对象序列化后,将其转换为字节序列,这些字节可以被保存在磁盘上和进行网络传输,序列化后的对象以二进制状态保存,保证了平台无关性。
使用序列化保存对象信息
Java中只有实现了java.io.Serializable接口的类的对象才能被序列化。
(1)创建一个对象输出流(ObjectOutputStream),它可以包装一个其他类型的输出流,如文件输出流FileOutputStream。
(2)通过对象输出流的writeObject()方法写对象,也就是输出序列化对象。
ObjectOutputStream oos = null;
try{
// 创建ObjectOutputStream 输出流
oos = new ObjectOutputStream (new FileOutputStream("D:\\test.txt"));
Test t = new Test("测试", 1, "2023-3-20");
// 对象序列化
oos.writeObject(t);
}catch(IOException e){
e.printStackTrace();
}finally{
if(oos!=null){
try{
oos.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
// 创建ObjectOutputStream 输出流
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream("D:\\test.txt"));
Test t1 = new Test("测试1", 1, "2023-3-20");
Test t2 = new Test("测试2", 2, "2023-3-20");
ArrayList<Test> list = new ArrayList<Test>();
list.add(t1);
list.add(t2);
// 对象序列化,写入输出流
oos.writeObject(list);
使用反序列化获取对象信息
通过反序列化,将存储在文件上的对象信息读取出来,重新构建为对象。
(1)创建一个对象输入流(ObjectInputStream),它可以包装一个其他类型的输入流,如文件输入流FileInputStream。
(2)通过对象输入流的readObject()方法读取对象。
ObjectInputStream ois = null;
try{
// 创建ObjectInputStream 输入流
ois = new ObjectInputStream (new FileInputStream("D:\\test.txt"));
// 反序列化,进行强制类型转换
Test t = (Test)ois.readObject();
// 输出对象
System.out.println(t.getName());
System.out.println(t.getNo());
System.out.println(t.getTime());
}catch(IOException e){
e.printStackTrace();
}finally{
if(ois !=null){
try{
ois .close();
}catch(IOException e){
e.printStackTrace();
}
}
}
// 创建ObjectInputStream 输入流
ObjectInputStream ois = new ObjectInputStream (new FileInputStream("D:\\test.txt"));
// 反序列化,进行强制类型转换
ArrayList<Test> list = (ArrayList<Test>)ois.readObject();
// 输出对象
for(Test t:list){
System.out.println(t.getName());
System.out.println(t.getNo());
System.out.println(t.getTime());
}
处于对安全的考虑,某些属性应限制被序列化,使用transient修饰。
对象引用的序列化
如果一个类的成员包含其他类的对象,当需要序列化此类时,要保证各个成员对象也是可序列化的。
序列化的算法规则:
- 所有保存到磁盘中的对象都有一个序列号;
- 当程序试图序列化一个对象时,将检查是否已经被序列化,只有被序列化后的对象才能被转换成字节序列输出;
- 如果对象已经被序列化,则程序直接输出一个序列化编号,而不再重新序列化。