java中的序列化和transient

一、序列化的含义、意义及使用场景

  • 序列化:将对象写入到IO流中
  • 反序列化:从IO流中恢复对象
  • 意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
  • 使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:程序创建的每个JavaBean类都实现Serializeable接口。

二、序列化实现的方式

如果需要将某个对象保存到磁盘上或者通过网络传输,那么这个类应该实现Serializable接口或者Externalizable接口之一。

1、Serializable

1.1 普通序列化

Serializable接口是一个标记接口,不用实现任何方法。一旦实现了此接口,该类的对象就是可序列化的。

  1. 序列化步骤:
  • 步骤一:创建一个ObjectOutputStream输出流;

  • 步骤二:调用ObjectOutputStream对象的writeObject输出可序列化对象。

    public class Person implements Serializable {
      private String name;
      private int age;
      //我不提供无参构造器
      public Person(String name, int age) {
          this.name = name;
          this.age = age;
      }
    
      @Override
      public String toString() {
          return "Person{" +
                  "name='" + name + '\'' +
                  ", age=" + age +
                  '}';
      }
    }
    
    public class WriteObject {
      public static void main(String[] args) {
          try (//创建一个ObjectOutputStream输出流
               ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"))) {
              //将对象序列化到文件s
              Person person = new Person("9龙", 23);
              oos.writeObject(person);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
    }
    
  1. 反序列化步骤:
  • 步骤一:创建一个ObjectInputStream输入流;

  • 步骤二:调用ObjectInputStream对象的readObject()得到序列化的对象。

    我们将上面序列化到person.txt的person对象反序列化回来

    public class Person implements Serializable {
      private String name;
      private int age;
      //我不提供无参构造器
      public Person(String name, int age) {
          System.out.println("反序列化,你调用我了吗?");
          this.name = name;
          this.age = age;
      }
    
      @Override
      public String toString() {
          return "Person{" +
                  "name='" + name + '\'' +
                  ", age=" + age +
                  '}';
      }
    }
    
    public class ReadObject {
      public static void main(String[] args) {
          try (//创建一个ObjectInputStream输入流
               ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt"))) {
              Person brady = (Person) ois.readObject();
              System.out.println(brady);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
    }
    //输出结果
    //Person{name='9龙', age=23}
    

    waht???? 输出告诉我们,反序列化并不会调用构造方法。反序列的对象是由JVM自己生成的对象,不通过构造方法生成。

1.2 成员是引用的序列化

如果一个可序列化的类的成员不是基本类型,也不是String类型,那这个引用类型也必须是可序列化的;否则,会导致此类不能序列化。

看例子,我们新增一个Teacher类。将Person去掉实现Serializable接口代码。

public class Person{
    //省略相关属性与方法
}
public class Teacher implements Serializable {

    private String name;
    private Person person;

    public Teacher(String name, Person person) {
        this.name = name;
        this.person = person;
    }

     public static void main(String[] args) throws Exception {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("teacher.txt"))) {
            Person person = new Person("路飞", 20);
            Teacher teacher = new Teacher("雷利", person);
    
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值