Java中对象的序列化与反序列化常用方法

对象序列化有什么用

在Java中我们可以在内存中创建多个可复用的Java对象,但是这些对象只有在JVM运行时才会存在,在实际运用中我们可能会遇到在JVM停止运行后还能保存对象、在网络中传输对象等需求。这时序列化技术就可以帮助我们实现这些需求。

序列化的方式

1.实现Serializable接口

这是使用最多的一种方式,Serializable接口是一个空接口,不需要我们重写任何方法,它的主要作用就是用来标识可以序列化。

下面是一些具体的例子:

单个对象的序列化

Students类

public class Students implements Serializable {
    private String Num;         //学号
    private String Name;        //学生姓名
    private int Age;            //学生年龄
    
    public Students(String Num,String Name,int Age){
        this.Num=Num;
        this.Name=Name;
        this.Age=Age;
    }

    public Students(){

    }

    public String getNum() {
        return Num;
    }
    public void setNum(String num) {
        Num = num;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public int getAge() {
        return Age;
    }
    public void setAge(int age) {
        Age = age;
    }

    @Override
    public String toString() {
        return "Students{" +
                "Num='" + Num + '\'' +
                ", Name='" + Name + '\'' +
                ", Age=" + Age +
                '}';
    }
}
import java.io.*;

public class Test4 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        serialization();
        deserialization();
    }

    // 序列化
    public static void serialization() throws IOException {
        File file = new File("d.txt");
        OutputStream os = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(os);
        oos.writeObject(new Students("10001","张三",20));
        oos.close();

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

    // 反序列化
    public static void deserialization() throws IOException, ClassNotFoundException {
        File file = new File("d.txt");

        InputStream is = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(is);
        Students students = (Students) ois.readObject();

        System.out.println(students);

        ois.close();
        System.out.println("反序列化成功");
    }
}

运行后可以看到生成了一个.txt文件并输出成功
在这里插入图片描述
当我们需要同时保存多个对象时,我们可以把对象放进数组或者集合中,这里重点介绍集合的序列化。通过阅读我们常用的几个集合ArrayList、LinkedList、HashSet、HashMap等我们都可以看到他们都实现了Serializable接口,所有我们也可以直接进行序列化。

import java.io.*;
import java.util.*;

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

       serialization();
       deserialization();

    }


    // 序列化
    public static void serialization() throws IOException {
        // ArrayList
        //ArrayList list = new ArrayList();
        // LinkList
        //LinkedList list = new LinkedList();
        // HashSet
        //HashSet list = new HashSet();
        // HashMap
        //HashMap<Integer,Students> map = new HashMap<>();
        // TreeMap
        TreeMap<Integer,Students> map = new TreeMap<>();


        Students student1 = new Students("10001","张三",20);
        Students student2 = new Students("10002","李四",21);
        Students student3 = new Students("10003","王五",22);
        /*
        list.add(student1);
        list.add(student2);
        list.add(student3);
        */
        map.put(1,student1);
        map.put(2,student2);
        map.put(3,student3);

        File file = new File("a.txt");
        OutputStream os = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(os);
        oos.writeObject(map);
        oos.close();

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

    // 反序列化
    public static void deserialization() throws IOException, ClassNotFoundException {
        File file = new File("a.txt");

        InputStream is = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(is);

        //ArrayList<Students> list = (ArrayList<Students>) ois.readObject();
        //LinkedList<Students> list = (LinkedList<Students>) ois.readObject();
        //HashSet<Students> list = (HashSet<Students>) ois.readObject();
        //HashMap<Integer,Students> map = (HashMap<Integer, Students>) ois.readObject();
        TreeMap<Integer,Students> map = (TreeMap<Integer, Students>) ois.readObject();

        /*
        for (Students s : list) {
            System.out.println(s.getNum()+"\t"+ s.getName()+"\t\t"+ s.getAge());
        }*/

        for (Integer key:map.keySet()) {
            System.out.println(map.get(key));
        }

        ois.close();
        System.out.println("反序列化成功");
    }

}

在这里插入图片描述

经过测试,都是没有问题的

在使用这种方法来序列化时我们还使用下面的3种方法来实现部分属性序列化
(1)使用transient修饰符
(2)使用static修饰符
(3)重写writeObject和readObject方法

2.实现Externalizable接口

Externalizable接口是继承于Serializable接口,可以说是Serializable接口的一个拓展,因为在实现Externalizable接口时我们必须重写writeExternal和readExternal这两个方法,重写时我们就可以指定要序列化的属性。

例子:
还是上面的Students类,不过得重写两个方法
这里我们就不对年龄这个属性进行序列化

public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(Num);
        out.writeObject(Name);
        //out.writeObject(Age);
    }
    
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        Num = (String) in.readObject();
        Name = (String) in.readObject();
        //Age = (int) in.readObject();
    }
import java.io.*;
import java.util.ArrayList;

public class Test3 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        serialization();
        deserialization();

    }

    public static void serialization() throws IOException {
        Students student1 = new Students("10001","张三",20);
        Students student2 = new Students("10002","李四",21);
        Students student3 = new Students("10003","王五",22);
        ArrayList list = new ArrayList();
        list.add(student1);
        list.add(student2);
        list.add(student3);

        File file = new File("c.txt");

        OutputStream os = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(os);
        oos.writeObject(list);

        oos.close();
    }

    public static void deserialization() throws IOException, ClassNotFoundException {
        File file = new File("c.txt");

        InputStream is = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(is);

        ArrayList<Students> list = (ArrayList<Students>) ois.readObject();

        for (Students s : list) {
            System.out.println(s.getNum()+"\t"+ s.getName()+"\t\t"+ s.getAge());
        }
    }
}

在这里插入图片描述

两种方法进行对比,Serializable接口实现更简单,但是执行效率会比Externalizable接口低,保存时占用的空间也更大。
为了方便使用我们可以把这两个方法包装成一个类,当需要序列化时就可以直接调用。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值