Java 序列化与反序列化

发布于 2023-07-16 14:59:56 字数 4508 浏览 35 评论 0

Java 序列化是将一个对象转化为字节流的过程,可以用于对象的存储、传输以及远程调用等。Java 反序列化是将字节流转化为对象的过程。

Java 提供了两种实现序列化和反序列化的方式:

使用 Serializable 接口

可以让一个类实现 Serializable 接口,该接口没有方法,只是起到标识作用。使用 ObjectOutputStream 类的 writeObject() 方法可以将一个对象序列化为字节流,使用 ObjectInputStream 类的 readObject() 方法可以将字节流反序列化为对象。

示例代码:

import java.io.*;

class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String username;
    private transient String password; // transient 关键字表示该字段不会被序列化

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}

public class SerializationExample {
    public static void main(String[] args) {
        User user = new User("admin", "123456");

        try {
            // 序列化对象
            FileOutputStream fileOutputStream = new FileOutputStream("user.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(user);
            objectOutputStream.close();
            fileOutputStream.close();
            System.out.println("Object serialized successfully.");

            // 反序列化对象
            FileInputStream fileInputStream = new FileInputStream("user.ser");
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            User deserializedUser = (User) objectInputStream.readObject();
            objectInputStream.close();
            fileInputStream.close();
            System.out.println("Object deserialized successfully.");
            System.out.println("Username: " + deserializedUser.getUsername());
            System.out.println("Password: " + deserializedUser.getPassword());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

使用 Externalizable 接口

如果一个类实现 Externalizable 接口,则必须实现其中的 readExternal() 和 writeExternal() 方法,可以在这两个方法中指定对象的序列化和反序列化方式。

示例代码:

import java.io.*;

class User implements Externalizable {
    private String username;
    private transient String password;

    public User() {
        // 默认构造方法,必须提供
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(username);
        out.writeObject(password);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        username = (String) in.readObject();
        password = (String) in.readObject();
    }
}

public class SerializationExample {
    public static void main(String[] args) {
        User user = new User("admin", "123456");

        try {
            // 序列化对象
            FileOutputStream fileOutputStream = new FileOutputStream("user.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            objectOutputStream.writeObject(user);
            objectOutputStream.close();
            fileOutputStream.close();
            System.out.println("Object serialized successfully.");

            // 反序列化对象
            FileInputStream fileInputStream = new FileInputStream("user.ser");
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            User deserializedUser = (User) objectInputStream.readObject();
            objectInputStream.close();
            fileInputStream.close();
            System.out.println("Object deserialized successfully.");
            System.out.println("Username: " + deserializedUser.getUsername());
            System.out.println("Password: " + deserializedUser.getPassword());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

需要注意的是,被序列化的类必须实现 Serializable 或 Externalizable 接口。同时,要保证序列化和反序列化的类的 serialVersionUID 属性保持一致,否则可能导致反序列化失败。另外,transient 关键字用于标记不需要被序列化的字段。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
22 人气
更多

推荐作者

xu362930323

文章 0 评论 0

缱倦旧时光

文章 0 评论 0

qq_eXruk9

文章 0 评论 0

遂心如意

文章 0 评论 0

guojiayue1

文章 0 评论 0

愿与i

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文