“在什么情况下类需要实现 Serializable,什么情况下又不需要(一)?”


学习 Java 的过程中,你可能会遇到这样的情况:有的类需要实现 Serializable,而有的类却不需要。这是为什么呢?其实,什么时候需要实现 Serializable,取决于对象怎么被使用,尤其是是否需要保存、传输。今天我就来解释一下这个问题。

Serializable 是什么?

简单来说,Serializable 是一个标记接口,表示某个类的对象可以被“打包”成一堆字节,方便保存到文件、发到网络另一端,或者放到缓存里。这个过程叫“序列化”,反过来把字节恢复成对象叫“反序列化”。

什么时候需要实现 Serializable

场景 1:需要保存或传输对象的时候

比如你有一个 User 类,代表一个用户的信息。你想把这个用户的数据存到文件里,或者通过网络发给别的服务处理。这时候,你就得让 User 实现 Serializable,因为你需要把它“打包”成字节流。

import java.io.Serializable;

public class User implements Serializable {
    private static final long serialVersionUID = 1L;  // 用来标识版本
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

这样你就能把这个 User 对象序列化,比如写进文件里:

User user = new User("Alice", 25);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.ser"));
out.writeObject(user);  // 把对象写到文件
out.close();

以后你可以把它从文件中“读回来”:

ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.ser"));
User user = (User) in.readObject();  // 反序列化,恢复对象
in.close();

在这种情况下,因为你需要把对象保存或传输,所以类必须实现 Serializable,否则就没法序列化对象。

什么时候不需要实现 Serializable

场景 2:对象只是程序内用,没必要保存或传输

有些类,比如临时做个计算,或者只是在程序里使用一下,根本不需要保存或者发送给其他服务。这种类就不需要实现 Serializable

例如,你写了个简单的计算器类,它只在内存里做加法操作:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

这个类只是在程序里运行,不会被保存到文件,也不会发给其他地方,所以没有必要让它实现 Serializable。实现了也是浪费。

前端返回数据为什么不需要 Serializable

当我们在后端给前端返回数据时,比如用 HTTP 接口,返回的通常是JSON 格式的数据。Java 对象会被转换成 JSON 字符串,这个过程和 Java 的序列化完全没关系,靠的是像 Jackson 这样的库。所以,即使你没有实现 Serializable,Java 还是能把对象变成 JSON 返回给前端。

比如在 Spring MVC 里,你可以写一个接口返回用户信息:

@RestController
public class UserController {
    @GetMapping("/user")
    public User getUser() {
        return new User("Alice", 25);
    }
}

用户发送请求后,后端会自动把 User 对象转换成 JSON,类似这样:

{
  "name": "Alice",
  "age": 25
}

整个过程里,JSON 是通过 Jackson 这样的工具处理的,根本不需要你去实现 Serializable。所以返回给前端时不需要实现 Serializable

为什么 Dubbo 需要实现 Serializable

Dubbo 是一个分布式服务框架,用来让不同服务器之间相互调用。当你使用 Dubbo 传输对象时,这些对象会被序列化成二进制字节流,通过网络传输。所以,像 User 这样的对象,如果要通过 Dubbo 传递,就必须实现 Serializable,否则它没法打包成字节流。

举个例子,假设你通过 Dubbo 调用一个远程服务,返回一个 User 对象:

public interface UserService {
    User getUser(String userId);
}

Dubbo 会把 User 对象打包成字节流传给客户端,这样客户端才能反序列化出一个 User 对象。如果 User 没有实现 Serializable,Dubbo 根本无法传输这个对象,调用就会失败。

因此,在 Dubbo 或其他分布式系统中,必须实现 Serializable,才能让对象通过网络传输

总结:什么时候需要实现 Serializable

  1. 需要实现 Serializable 的情况

    • 你想要把对象保存到文件里,或者通过网络传输,比如说用 Dubbo 调用远程服务。
    • 如果你要把对象存到缓存(如 Redis),也需要实现 Serializable
  2. 不需要实现 Serializable 的情况

    • 如果对象只在程序内使用,不会被保存或传输,比如临时计算类、工具类。
    • 在和前端交互时,通常返回的是 JSON 数据,不需要 Serializable,因为 Java 会把对象转换成 JSON 格式返回。

总的来说,是否需要实现 Serializable,取决于对象是不是需要被保存或传输。如果只是本地使用的临时对象,那就不需要去实现它;但如果是要跨系统、跨网络传输对象,就必须让类实现 Serializable

推荐阅读文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔道不误砍柴功

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值