将Java对象写入文件中

Java对象序列化

首先介绍一下对象序列化的目标:对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象。

一、序列化的含义和意义:
序列化机制使得对象可以脱离程序的运行而独立存在。
对象的序列化指将一个Java对象写入IO流中,与此对应的反是,对象的反序列化则指从IO流中恢复该Java对象。

如果需要需要让某个对象支持序列化机制,则必须让它的类是可序列化的(serializable)。为了让某个类是可序列化的,该类必须实现如下两个接口之一:

  • Serializable
  • Externalizable

Serializable接口是一个标记接口,实现该接口无需实现任何方法,它只是表明该类的实例是可序列化的。
所有需要保存到磁盘里的对象的类都应该可序列化。

二、使用对象流实现序列化(使用Serializable接口)
使用 Serializable 来实现序列化非常简单,主要让目标类实现 Serializable 标记接口即可,无须实现任何方法。

  • 一旦某个类实现了 Serializable 接口,该类的对象就是可序列化的,程序可以通过如下两个步骤来序列化该对象。

1.创建一个 ObjectOutputStream,这个输出流是一个处理流,所以必须建立在其他节点流的基础上。如下代码所示。

//创建 ObjectOutputStream 输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.txt));

2.调用 ObjectOutputStream 对象的writeObject()方法输出可序列化对象。如下代码所示。

//将一个对象输出到输出流中
oos.writeObject(text);
  • 如果希望从二进制流中恢复 Java对象,则需要使用反序列化。反序列化的步骤如下.

1.创建一个 ObjectInputStream 输入流,这个输入流是一个处理流,所以必须建立在其他节点流的基础之上。如下代码所示。

//创建一个ObjectInputStream()输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputstream("file.txt"));

2.调用 ObjectInputStream 对象的readObject()方法读取流中的对象,该方法返回一个 Object 类型的 Java 对象,如果程序知道该 Java 对象的类型,则可以将该对象强制类型转换成其真实的类型。如下代码所示。

//从输入流中读取一个 Java 对象,并将起强制类型转换为 Test 类
Test t = (Test) ois.readObject();

三、实例

  • 下面程序定义了一个 Student 类,这个 Student 就是一个普通的 Java 类,只是实现了 Serializable 接口,该接口标识该类的对象是可序列化的。
public class Student implements java.io.Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int num;
    private String name;
    public Student(int num, String name) {
        this.num = num;
        this.name = name;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
  • 下面程序使用 ObjectOutputStream 将一个 Student 对象写入磁盘文件
public class WriteObjcect {

    public static void main(String[] args) {
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Student.txt"));
            Student stu = new Student(1,"吴彦祖");
            oos.writeObject(stu);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面程序中的第四行代码创建了一个 ObjectOutputStream 输出流,这个 ObjectOutputStream 输出流建立在一个文件输出流的基础上;程序第六行代码使用 writeObject() 方法将一个 Student 对象写入输出流。运行上面程序,将会看到生成了一个 Student.txt 文件,该文件的内容就是 Student 对象。

  • 下面程序示范了从刚刚生成的 Student.txt 文件中读取 Student 对象的步骤
public class ReadObject {

    public static void main(String[] args) {
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Student.txt"));
            Student stu = (Student) ois.readObject();
            System.Out.println("名字为:" + p.getname() + "\n年龄为:" + p.getnum());
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

上面程序第四行代码将一个文件输入流包装成 ObjectInputStream 输入流,第五行代码使用 readObject() 读取了文件中的 Java 对象,这就完成了反序列化过程。

四、注意

  1. 反序列化读取的仅仅是 Java 对象的数据,而不是 Java 类,因此采用反序列化恢复 Java 对象时,必须提供该 Java 对象所属的 class 文件,否则将会引发 ClassNotFoundException 异常。
  2. Student 类只有一个有参的构造器,没有无参的构造器,而且该构造器内有一个普通的打印语句。当反序列化 Java 对象时,并没有看到程序调用该构造器,这表明反序列化机制无须通过构造器来初始化 Java 对象。
  3. 如果使用序列化机制向文件中写入了多个 Java 对象,使用反序列化机制恢复对象时必须按实际写入的顺序读取。
  4. 当一个可序列化对象有多个父类时(包括直接父类和间接父类),这些父类要么有无参的构造器,要么也是可序列化的——否则反序列化时将抛出 InvalidClassException 异常。如果父类是不可序列化的,只是带有无参构造器,则该父类中定义的成员变量值不会序列化到二进制流中。

                                                                                        **end**
  • 20
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值