java序列化机制

知识目标
1.掌握对象序列化的基本概念。
2.掌握对象序列化的方法。
能力目
标熟练使用对象的序列化编写相应应用程序。
素质目标
1. 能够阅读科技文档和撰写分析文档。
2. 能够查阅JDK API。
3. 增强学生团队协作能力。

列化是一种将对象以一连串的字节进行描述的过程,用于解决在对对象流进行读写操作时所引发的问题。序列化可以将对象的状态写在流里进行网络传输,或者保存到文件、数据库等系统中,并在需要时把该流读取出来重新构造一个相同的对象。

序列化的概念

将在内存中的各种对象的状态(也就是实例变量,不是方法)保存在磁盘中或者在网络中进行传输,并且可以把保存的对象状态再读出来。将一个Java对象写入IO流;与此对应的,则是从IO流中恢复一个Java对象。Java提供这种保存对象状态的机制,就是序列化。对象序列化是Java编程中的必备武器。

任务实施

任务一 使用Serializable序列化实体对象

1、任务需求

将一个对象序列化后写入到本地文件中。

2.任务分析

本任务类图如图5-1所示。

 Employee.Java类是一个可序列化的实体类,要实现Serializable接口,同时需要有一个成员变量serialVersionUID。Address.Java类描述员工的地址信息。TestSerialize.Java类是测试类。文件是:D:\employee.dat。实现Serializable接口非常简单,只要让Java实现Serializable接口即可,无须实现任何方法。一个类一旦实现了Serializable接口,那么该类的对象就是可序列化的。实现类的对象的序列化可以使用ObjectOutputStream,实现步骤如下。• 创建ObjectOutputStream对象;• 调用ObjectOutputStream的writeObject方法输出对象。

3、任务实现

(1)地址类Address.java

package 序列化.使用Serializable序列化实体对象;
import java.io.Serializable;
public class Address implements Serializable {
    private static final long serialVersionUID = 4983187287403615604L;
    private String state; // 表示员工所在的国家
    private String province; // 表示员工所在的省
    private String city; // 表示员工所在的市
    public Address(String state, String province, String city) {// 利用构造方法初始化各个域
        this.state = state;
        this.province = province;
        this.city = city;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
    @Override
    public String toString() {// 使用地址属性表示地址对象
        StringBuilder sb = new StringBuilder();
        sb.append("国家:" + state + ", ");
        sb.append("省:" + province + ", ");
        sb.append("市:" + city);
        return sb.toString();
    }
} 

(2)员工类Employee.Java

package 序列化.使用Serializable序列化实体对象;

import java.io.Serializable;
public class Employee implements Serializable {
    private static final long serialVersionUID = 3049633059823371192L;
    private String name; // 表示员工的姓名
    private int age; // 表示员工的年龄
    private Address address;// 表示员工的地址
    // 利用构造方法初始化各个域
    public Employee(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    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 Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    public String toString() {// 重写toString()方法
        StringBuilder sb = new StringBuilder();
        sb.append("姓名:" + name + ", ");
        sb.append("年龄:" + age + "\n");
        sb.append("地址:" + address);
        return sb.toString();
    }
}

(3)测试类TestSerialize.Java

package 序列化.使用Serializable序列化实体对象;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TestSerialize {
    public static void main(String[] args) {
        // 创建一个员工对象
        Address address = new Address("中国", "吉林", "长春");// 创建address对象
        Employee employee = new Employee("张XX", 30, address);// 创建employee对象
        // 将该对象写入到文件中,序列化该对象
        File file = new File("employee.dat");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(employee);
            oos.flush();
            oos.close();
            fos.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

//        try{
//            FileInputStream fis = new FileInputStream(file);
//            ObjectInputStream ois = new ObjectInputStream(fis);
//            Object o = ois.readObject();
//            System.out.println(o.toString());
//
//            ois.close();
//            fis.close();
//
//        } catch (FileNotFoundException e) {
//            throw new RuntimeException(e);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        } catch (ClassNotFoundException e) {
//            throw new RuntimeException(e);
//        }



    }
}

任务二 使用反序列化将Person对象从磁盘上读出

1. 任务需求

使用反序列化将Employee对象从磁盘上读出并修改员工信息,然后再写入到文件中。

2. 任务分析

相应的反序列化需要使用的类是ObjectInputStream,反序列化的步骤如下。• 创建ObjectInputStream对象;• 使用ObjectInputStream的readObject方法取出对象。

3. 任务实现 

重构代码,实现反序列化,代码如下。

TestDeserialize.java

package 序列化.使用Serializable序列化实体对象;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TestDeserialize {
    public static void main(String[] args) {
        File file = new File("employee.dat");
        // 从文件中读取对象,反序列化该对象
        Employee employee1 = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            employee1 = (Employee) ois.readObject();
            System.out.println("修改前员工的信息:");
            System.out.println(employee1);// 输出employee对象
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 修改该员工的相关信息
        employee1.getAddress().setState("中国");
        employee1.getAddress().setProvince("湖北省");
        employee1.getAddress().setCity("武汉市");
        employee1.setAge(21);
        // 将该员工对象再次写入文件中,进行序列化
        try {
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(employee1);
            oos.flush();
            oos.close();
            fos.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 再次从文件中读取对象,进行反序列化
        Employee employee2 = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);
            employee2 = (Employee) ois.readObject();
            System.out.println("修改后员工的信息:");
            System.out.println(employee2);// 输出employee对象
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

说明

关于对象序列化与反序列化还有几点需要注意。• 反序列化无须通过构造器初始化对象;• 如果使用序列化机制向文件中写入了多个对象,那么取出和写入的顺序必须一致;• Java对类的对象进行序列化时,若类中存在对象引用(且值不为null),也会对类的引用对象进行序列化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java序列机制Java语言中的一种重要机制,它可以将Java对象转换为字节序列,以便在网络上传输或在文件中存储。Java序列机制由两个部分组成:序列和反序列。 1. 序列 序列是将Java对象转换为字节序列的过程,这个过程可以通过将对象写入输出流来完成。Java提供了两个主要的序列类:ObjectOutputStream和ObjectInputStream。 ObjectOutputStream类是用来将Java对象写入输出流的,它可以将Java对象转换为字节序列,并将字节序列写入输出流。序列的过程中,ObjectOutputStream会将对象的类信息和实例数据都写入输出流中。 2. 反序列序列是将字节序列转换为Java对象的过程,这个过程可以通过读取输入流来完成。Java提供了两个主要的反序列类:ObjectInputStream和ObjectOutputStream。 ObjectInputStream类是用来从输入流中读取字节序列的,并将其转换为Java对象。反序列的过程中,ObjectInputStream会从输入流中读取对象的类信息和实例数据,并重新创建Java对象。 3. 序列机制的实现原理 Java序列机制的实现原理是通过将Java对象转换为字节序列并将其写入输出流中,然后通过读取输入流将字节序列转换为Java对象。 Java序列机制的实现过程中,所有的类都必须实现Serializable接口。这个接口没有任何方法,只是标识了该类可以被序列Java序列机制还需要注意一些问题,比如序列的版本号、序列的安全性、序列的性能等。为了提高序列的性能,可以使用一些优技巧,比如使用transient关键字防止某些字段被序列、使用Externalizable接口替代Serializable接口等。 总之,Java序列机制Java语言中非常重要的一种机制,它可以实现Java对象的跨平台传输和持久存储。在开发中,需要注意序列的版本号、安全性和性能等问题,以确保程序的正确性和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值