Java的序列化和反序列化

序列化和反序列化的介绍

将类的对象写入文件,并可以通过文件恢复原来的对象,这便是序列化与反序列化;
对于需要写入读出的类需要实现 Serializable或Externalizable,实现 Serializable接口较为简单一些

关于 Serializable 与 Externalizable 的对比,可以简单归结为:Externalizable 是 Serializable 的子接口,里面给出了抽象方法,要求实现类进行重写,方便对部分属性进行序列化

实现Serializable接口的序列化与反序列化

这个不要求类具有空构造函数,且实现较为简单,推荐使用这个
同时只会对没有 static / transient 修饰的属性进行序列化

进行序列化与反序列化的时候需要注意的问题:包的位置,在进行序列化的时候会将包的信息写入,所以需要共用同一个包下的同一个类;以及对象序列化时需要实现 Serializable接口,如果成员也是类的对象的时候,也需要实现 Serializable接口(如果父类已经实现过则会继承给子类,所以这时子类是不用再实现Serializable接口的)

package com.boot.test;

import java.io.*;
import java.nio.file.Files;

/**
 * @author bbyh
 * @date 2022/11/2 0002 10:19
 * @description
 */
public class FileTest implements Serializable {
	private static final long serialVersionUID = 1L;
	
    private final String name;
    private final Integer age;

    public FileTest(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "FileTest{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public static void main(String[] args) {
        test1();
        test2();
    }

    public static void test1() {
        File file = new File("D:/test.txt");

        try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
            outputStream.writeObject(new FileTest("Jack", 20));
            System.out.println("Write Success");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void test2() {
        File file = new File("D:/test.txt");

        try (ObjectInputStream inputStream = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
            FileTest fileTest = (FileTest) inputStream.readObject();
            System.out.println(fileTest);
            System.out.println("Read Success");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

实现Externalizable接口的序列化与反序列化

Externalizable 接口是实现了 Serializable 接口的

这个接口实现序列化,我真没搞懂,感觉挺鸡肋的,不是必须要无参构造,即你可以直接读入,然后通过有参构造创建对象,但是有无参构造会书写规范一些

另外,我通过直接像 Serializable 接口一样直接写入整个对象时,一直无法正确读出对象,必须要一个一个写入才行,感觉不好用

package com.boot.test;

import java.io.*;
import java.nio.file.Files;

/**
 * @author bbyh
 * @date 2022/11/2 0002 10:19
 * @description
 */
public class FileTest implements Externalizable {
    private static final long serialVersionUID = 1L;

    private String name;
    private Integer age;

    public FileTest(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "FileTest{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public static void main(String[] args) {
        FileTest fileTest = new FileTest("Jack", 20);
        fileTest.test1();
        fileTest.test2();
    }

    public void test1() {
        File file = new File("D:/test.txt");

        try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
            writeExternal(outputStream);
            System.out.println("Write Success");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void test2() {
        File file = new File("D:/test.txt");

        try (ObjectInputStream inputStream = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
            readExternal(inputStream);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(this.name);
        out.writeObject(this.age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        FileTest fileTest = new FileTest((String) in.readObject(), (Integer) in.readObject());
//        fileTest.name = (String) in.readObject();
//        fileTest.age = (Integer) in.readObject();
        System.out.println(fileTest);
        System.out.println("Read Success");
    }
}

当然也可以通过自己的代码写,就不在需要实现的方法里面写;只是这样的话,代码确实会较为混乱一些

这样的情况下,同样是无法直接一次性写入全部的对象,需要一个个写入,不能说一点用都没有,只能说看着也不想用

package com.boot.test;

import java.io.*;
import java.nio.file.Files;

/**
 * @author bbyh
 * @date 2022/11/2 0002 10:19
 * @description
 */
public class FileTest implements Externalizable {
    private static final long serialVersionUID = 1L;

    private String name;
    private Integer age;

    public FileTest(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public FileTest() {
    }

    @Override
    public String toString() {
        return "FileTest{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public static void main(String[] args) {
        test1();
        test2();
    }

    public static void test1() {
        File file = new File("D:/test.txt");

        try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
            FileTest fileTest = new FileTest("jack", 20);
            outputStream.writeObject(fileTest.name);
            outputStream.writeObject(fileTest.age);
            System.out.println("Write Success");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void test2() {
        File file = new File("D:/test.txt");

        try (ObjectInputStream inputStream = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
            FileTest fileTest = new FileTest();
            fileTest.name = (String) inputStream.readObject();
            fileTest.age = (Integer) inputStream.readObject();
            System.out.println(fileTest);
            System.out.println("Read Success");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {

    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值