Java安全基础之Java序列化与反序列化

打印 上一主题 下一主题

主题 865|帖子 865|积分 2595

目次

Java 的序列化(Serialization)是指将对象转换为字节序列的过程,而反序列化(Deserialization)则是将字节序列转换回对象的过程。
序列化和反序列化通常用于在网络上传输对象或者将对象持久化到文件体系中。
Java 提供了 java.io.Serializable 接口来支持对象的序列化和反序列化。如果一个类实现了 Serializable 接口,那么该类的对象就可以被序列化和反序列化。
ObjectInputStream 和 ObjectOutputStream

ObjectInputStream 和 ObjectOutputStream 是 Java 中用于序列化和反序列化对象的类,它们提供了将对象转换为字节省并将字节省转换回对象的功能。

  • ObjectOutputStream:用于将对象序列化为字节省,依赖于 writeObject() 方法。
  • ObjectInputStream:用于从字节省反序列化对象,依赖于 readObject() 方法。
  1. try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.ser"))) {
  2.     // 写入对象到文件
  3.     out.writeObject(myObject);
  4. } catch (IOException e) {
  5.     e.printStackTrace();
  6. }
  7. try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.ser"))) {
  8.     // 从文件中读取对象
  9.     MyObject myObject = (MyObject) in.readObject();
  10. } catch (IOException | ClassNotFoundException e) {
  11.     e.printStackTrace();
  12. }
复制代码
java.io.Serializable

Serializable 这个接口本身并不包含任何方法,它只是一个空接口,其作用是告诉 Java 编译器,这个类的对象可以被序列化成字节省,也可以从字节省中反序列化成对象。
利用文件流进行序列化: 将对象序列化到文件中,利用 FileOutputStream 和 FileInputStream 进行读写操纵。
  1. import java.io.*;
  2. public class SerializationExample {
  3.     public static void main(String[] args) {
  4.         try {
  5.             String obj = "serialization example";
  6.             // 序列化对象到文件
  7.             FileOutputStream fos = new FileOutputStream("object.ser");
  8.             ObjectOutputStream os = new ObjectOutputStream(fos);
  9.             os.writeObject(obj);
  10.             os.close();
  11.             //反序列化对象到文件
  12.             FileInputStream fis = new FileInputStream("object.ser");
  13.             ObjectInputStream ois = new ObjectInputStream(fis);
  14.             String dobj = (String)ois.readObject();
  15.             System.out.print(dobj);
  16.             ois.close();
  17.         } catch (IOException | ClassNotFoundException e) {
  18.             throw new RuntimeException(e);
  19.         }
  20.     }
  21. }
复制代码
利用字节数组进行序列化: 还可以利用 ByteArrayOutputStream 将对象序列化到字节数组中。
  1. import java.io.*;
  2. public class SerializationExample {
  3.     public static void main(String[] args) {
  4.         try {
  5.             String obj = "serialization example";
  6.             // 序列化对象到字节数组
  7.             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  8.             ObjectOutputStream os = new ObjectOutputStream(byteArrayOutputStream);
  9.             os.writeObject(obj);
  10.             os.close();
  11.             // 从字节数组反序列化对象
  12.             byte[] byteArray = byteArrayOutputStream.toByteArray();
  13.             ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
  14.             ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream);
  15.             String dobj = (String) ois.readObject();
  16.             System.out.print(dobj);
  17.             ois.close();
  18.         } catch (IOException | ClassNotFoundException e) {
  19.             throw new RuntimeException(e);
  20.         }
  21.     }
  22. }
复制代码
除了可以将对象序列化到文件流和字节数组,还可以将对象序列化到网络流、缓存流等。除了 Java 原生的序列化方式外,还有一些第三方库可以进行对象的序列化,例如 JSON 序列化或者 XML 序列。
自定义序列化和反序列化

在 Java 中,可以通过实现 writeObject() 和 readObject() 方法来自定义序列化和反序列化过程,可以更灵活地控制对象在序列化和反序列化过程中的行为。

  • 自定义序列化:private void writeObject(ObjectOutputStream oos)
  • 自定义反序列化:private void readObject(ObjectInputStream ois)
例如:Person 类实现了 Serializable 接口
  1. class Person implements Serializable {
  2.     private String name;
  3.     private transient int age; // transient 表示该字段不参与序列化
  4.     public Person(String name, int age) {
  5.         this.name = name;
  6.         this.age = age;
  7.     }
  8.     // 自定义序列化方法
  9.     private void writeObject(ObjectOutputStream out) throws IOException {
  10.         out.defaultWriteObject(); // 默认序列化其他字段
  11.         // 手动序列化 age 字段
  12.         out.writeInt(age);
  13.     }
  14.     // 自定义反序列化方法
  15.     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
  16.         in.defaultReadObject(); // 默认反序列化其他字段
  17.         // 手动反序列化 age 字段
  18.         age = in.readInt();
  19.     }
  20. }
复制代码
在待序列化或反序列化的类中定义 readObject 和 writeObject 方法,就来实现了自定义的序列化和反序列化操纵。
若有错误,接待指正!o( ̄▽ ̄)ブ

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

兜兜零元

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表