Java的输入/输出——对象序列化

1、序列化简介

对象序列化是将对象状态转化为可保持或传输的格式的过程,一般而言对象序列化有以下作用:

  • RMI(远程方法调用机制),网络传输,通过各个Socket作为对象之间的通信,从而实现程序组件在不同操作系统之间的通信,RMI大大增加了Java开发分布式应用的能力
  • 将对象转化成文件,可保存到硬盘上,将对象储存起来,以便将来继续使用该对象
  • 通过序列化在进程之间传递对象

序列化一个对象需要让他实现Serializable接口,Serializable接口是一个标记接口,不需要实现任何方法,Serializable接口的定义如下:

public interface Serializable { 
}

Java对象被序列化时参与序列化的内容如下:

  1. 属性:如基本数据类型、数组和其他对象的引用
  2. 类名

不能被序列化的内容有:

  • 方法,类中的所有方法
  • static关键字和transient 关键字修饰的属性(transient 当前属性的数据不参与序列化和反序列化)

2、对象输出流:ObjectOutputStream

java.io.ObjectOutputStream类用于对象的序列化,即将一个对象输出,它实现了OutputStream接口,它的定义为:

public class ObjectOutputStream extends OutputStream implements ObjectOutputObjectStreamConstants

常用方法为:
这里写图片描述

3、对象输入流:ObjectInputStream

ObjectInputStream类用于对对象进行反序列化操作,ObjectInputStream类的定义如下:

public class ObjectInputStream extends InputStream implements ObjectInputObjectStreamConstants

这里写图片描述

实例:

/**
 * 定义一个可序列化的类Student
 * @author lzq
 *
 */
public class Student implements Serializable {
    private String name;
    private int age;
    private String school;
    public Student() {

    }
    public Student(String name,int age,String school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }
    public void tell() {
        System.out.println("名字:"+name+"\n年龄:"+age+"\n学校:"+school);
    }

}
/**
 * 用Serializable接口
 * 对象的序列化和反序列化
 * @author lzq
 *
 */
public class TestDemo11  {
    public static void main(String[] args) {
        File file = new File("D:\\lzq/ObjectStudent.txt");
        serializable(file);
        deserializable(file);
    }
    /**
     * 对象序列化
     * @param file
     */
    public static void serializable(File file) {
        Student stu1 = new Student("小强",21,"哈佛");
        Student stu2 = new Student("小红",22,"剑桥");
        try {
            FileOutputStream fout = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject(stu1);
            oos.writeObject(stu2);
            oos.close();
            fout.close();
        }catch(Exception e) {
            e.printStackTrace();
        }

    }
    /**
     * 对象反序列化
     * @param file
     */
    public static void deserializable(File file) {
        try {
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student stu1 = (Student)ois.readObject();
            Student stu2 = (Student)ois.readObject();
            ois.close();
            fis.close();
            stu1.tell();
            stu2.tell();
        }catch(IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

运行结果:
保存的是二进制文件:
这里写图片描述

名字:小强
年龄:21
学校:哈佛
名字:小红
年龄:22
学校:剑桥

4、Externalizable接口

Java序列化有两种实现方法,一种是在类定义的时候实现Serializable接口,另一种是实现Externalizable接口,被Serializable接口声明的对象的内容都将被序列化,而Externalizable接口声明的类的对象可以选择需要序列化的内容,Externalizable接口定义了readExternal()和writeExternal()方法,实现该接口必须实现这两种方法

实现Externalizable接口:

public class Student implements Externalizable {
    private String name;
    private int age;
    private String school;
    public Student() {

    }
    public Student(String name,int age,String school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }
    public void tell() {
        System.out.println("名字:"+name+"\n年龄:"+age+"\n学校:"+school);
    }
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.name = (String)in.readObject();
            this.school = (String)in.readObject();

    }
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(this.name);
        out.writeObject(this.school);  //选择name、school两个被序列化
    }

}
/**
 * 用Externalizable接口
 * 对象的序列化和反序列化
 * @author lzq
 *
 */
public class TestDemo12 {


    public static void main(String[] args) {
        File file = new File("D:\\lzq/Externalizable.txt");
        serialize(file);
        deserialize(file);

    }

    /**
     * 对象的序列化
     * @param file
     */
    private static void serialize(File file) {
        Student stu1 = new Student("小强",21,"哈佛");
        Student stu2 = new Student("小红",22,"剑桥");
        try {
            FileOutputStream fout = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject(stu1);
            oos.writeObject(stu2);
            oos.close();
            fout.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    private static void deserialize(File file) {
        try {
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student stu1 = (Student)ois.readObject();
            Student stu2 = (Student)ois.readObject();
            ois.close();
            fis.close();
            stu1.tell();
            stu2.tell();
        }catch(IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


}

运行结果:

名字:小强
年龄:21
学校:哈佛
名字:小红
年龄:22
学校:剑桥

使用transient关键字声明不需要序列化的属性

public class Student implements Serializable {
    private String name;
    private transient int age;  //使用transient声明age属性不需要被序列化
    private String school;
    public Student() {

    }
    public Student(String name,int age,String school) {
        this.name = name;
        this.age = age;
        this.school = school;
    }
    public void tell() {
        System.out.println("名字:"+name+"\n年龄:"+age+"\n学校:"+school);
    }

}
/**
 * 用Serializable接口
 * 对象的序列化和反序列化
 * @author lzq
 *
 */
public class TestDemo11  {
    public static void main(String[] args) {
        File file = new File("D:\\lzq/ObjectStudent.txt");
        serializable(file);
        deserializable(file);
    }
    /**
     * 对象序列化
     * @param file
     */
    public static void serializable(File file) {
        Student stu1 = new Student("小强",21,"哈佛");
        Student stu2 = new Student("小红",22,"剑桥");
        try {
            FileOutputStream fout = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fout);
            oos.writeObject(stu1);
            oos.writeObject(stu2);
            oos.close();
            fout.close();
        }catch(Exception e) {
            e.printStackTrace();
        }

    }
    /**
     * 对象反序列化
     * @param file
     */
    public static void deserializable(File file) {
        try {
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Student stu1 = (Student)ois.readObject();
            Student stu2 = (Student)ois.readObject();
            ois.close();
            fis.close();
            stu1.tell();
            stu2.tell();
        }catch(IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

运行结果:

名字:小强
年龄:0
学校:哈佛
名字:小红
年龄:0
学校:剑桥

age属性为0,说明age属性没有被序列化保存下来

猜你喜欢

转载自blog.csdn.net/QQ2899349953/article/details/81410752