Java核心API之对象流的使用介绍

2025-10-23 16:09:23

1、对象流的基本概念

    存在既有意义,对象流可以帮助我们将内存中的Java对象保存到本地磁盘,即字节序列。这种将Java对象转化为一个字节序列,就叫做对象序列化。反之,将一个序列文件转化为Java对象,这个过程称作反序列化。

    听起来对象流很高大上,其实很简单。在Java程序运行过程中,Java对象的属性值都存储在内存,程序结束后释放内存,一股青烟后,任何数据都会消失,为了将内存中的Java对象的属性状态保存到本地磁盘,于是对象流就应运而生。

Java核心API之对象流的使用介绍

2、Serializable接口

    说到对象序列化,必须要讲到Serializable接口。Java对象所属的类必须实现Serializable接口。实现这个接口不必重写任何方法,其只作为可序列化的标识。

    小编建议每一个实现Serializable接口的对象类,需要显示添加一个常数serialVersionUID,表明该类的版本。如果不添加该常数,对象序列化时会根据对象类的信息计算出默认的serialVersionUID的值。

    serialVersionUID就像我们的身份证一样,每次序列化时,java编译器会根据serialVersionUID确认java对象类。反序列化时,如果serialVersionUID不一致,会抛出InvalidClassException异常。

    Serializable接口稍后还会讲到,我们接着学习对象流的操作。

Java核心API之对象流的使用介绍

3、对象流之ObjectOutputStream对象序列化

    ObjectOutputStream可以将对象进行序列化的输出流。

示例代码如下:

//ObjectOutputStreamDemo类代码

  public class ObjectOutputStreamDemo{

 /*

  * void writeObject()

  * 将特定的对象转化为字节序列

  */

  @Test

  public void testOOS() throws Exception{

      FileOutputStream fos = new FileOutputStream("boy.obj");

   

      //构造方法ObjectOutputSteam(OutputStream out)

      ObjectOutputStream oos = new ObjectOutputStream(fos);

   

      Person boy = new Person("Peter",12,"男");

      oos.writeObject(boy);

      System.out.println("完成序列化");

      oos.close();

  }

}    

//Java对象类代码

public class Person implements Serializable {

     private static final long serialVersionUID = 1L;

     private String name;

     private int age;

     private String gender;

    

     public Person() {

         super();

     }

     public Person(String name, int age, String gender) {

         super();

         this.name = name;

         this.age = age;

         this.gender = gender;

     }

     public String getName() {

         return name;

     }

     public void setName(String name) {

         this.name = name;

     }

     public int getAge() {

         return age;

     }

     public void setAge(int age) {

         this.age = age;

     }

     public String getGender() {

         return gender;

     }

     public void setGender(String gender) {

         this.gender = gender;

     }

     @Override

     public String toString() {

         return "name=" + name + ", age=" + age + ", gender=" + gender ;

     }

}

注意:可以将上述代码片段粘贴到本地,运行测试,供大家参考,如果有问题可以联系小编。

Java核心API之对象流的使用介绍

Java核心API之对象流的使用介绍

4、对象流之ObjectInputStream对象反序列化

    ObjectInputStream可以将序列化转换成对象。

示例代码如下:

//ObjectInputStreamDemo类

public class ObjectInputStreamDemo{

/*

* Object readObject();

* 将对象序列化转换为对象

*/

@Test

public void testOIS() throws Exception{

    FileInputStream fis = new FileInputStream("boy.obj");

    ObjectInputStream ois = new ObjectInputStream(fis);

    //Object readObject()读取二进制文件转换成对象

    Person boy = (Person)ois.readObject();

    System.out.println(boy);

    System.out.println("反序列化操作完毕");

    ois.close();

 }

}

Java核心API之对象流的使用介绍

5、实现Serializable接口注意事项

    Java对象类实现Serializable接口后,显式声明serialVersionUID,确定Java对象所属类的版本。如果不显式声明,Java编译器会根据Java对象类的结构计算生成默认的serialVersionUID,这意味着每次修改Java对象类会重新生成默认的serialVersionUID,这样导致反序列化失败。

    下面代码有几处进行少量修改

    1)、显式声明的常量serialVersionUID注释掉;

    2)、然后修改Person类,添加体重(weight)的属性;

    3)、最后运行反序列化代码

    4)、查看运行结果。

示例代码如下:

//ObjectOutputStreamDemo类代码如下

  public class ObjectOutputStreamDemo{

 /*

  * void writeObject()

  * 将特定的对象转化为字节序列

  */

  @Test

  public void testOOS() throws Exception{

      FileOutputStream fos = new FileOutputStream("boy.obj");

   

      //构造方法ObjectOutputSteam(OutputStream out)

      ObjectOutputStream oos = new ObjectOutputStream(fos);

   

      Person boy = new Person("Peter",12,"男",50);

      oos.writeObject(boy);

      System.out.println("完成序列化");

      oos.close();

  }

}    

//ObjectInputStreamDemo类如下

public class ObjectInputStreamDemo{

/*

* Object readObject();

* 将对象序列化转换为对象

*/

@Test

public void testOIS() throws Exception{

    FileInputStream fis = new FileInputStream("boy.obj");

    ObjectInputStream ois = new ObjectInputStream(fis);

    //Object readObject()读取二进制文件转换成对象

    Person boy = (Person)ois.readObject();

    System.out.println(boy);

    System.out.println("反序列化操作完毕");

    ois.close();

 }

}

//Java对象类代码如下

public class Person implements Serializable {

   //private static final long serialVersionUID = 1L;

    private String name;

    private int age;

    private String gender;

    private int weight;

    

    

    public Person() {

        super();

    }

    public Person(String name, int age, String gender,int weight) {

        super();

        this.name = name;

        this.age = age;

        this.gender = gender;

        this.weight = weight;

    }

    public String getName() {

         return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public String getGender() {

        return gender;

    }

    public void setGender(String gender) {

        this.gender = gender;

    }

    public int getWeight(){

        return weight;

    }

    public void setWeight(int weight){

        this.weight = weight;

    }

   @Override

   public String toString() {

       return "name=" + name + ", age=" + age + ", gender=" + gender +", weight="+weight ;

   }

    

}

分析:对象序列化操作,对象所属类除了要实现Serializable接口外,还要显式声明serialVersionUID,确保对象类的版本一致,修改类信息后不会由于默认的serialVersionUID不一致而报错。

思考:大家可以将上述代码拷贝到本地运行测试,serialVersionUID不变,删除Person类的属性查看运行结果。

Java核心API之对象流的使用介绍

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢