ChatGPT解决这个技术问题 Extra ChatGPT

我们什么时候应该实现 Serializable 接口?

public class Contact implements Serializable {
    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

什么时候应该实现 Serializable 接口?我们为什么要这样做?它有什么优势或安全性吗?

仅供参考,此处接受的答案不完整且具有误导性,因为它没有解决安全缺陷。请参阅Effective Javaitem 86:非常谨慎地实现 Serializable。 Raedwald's answer here 说不使用序列化是正确的。

K
Kasun Siyambalapitiya

从这个“序列化”到底是什么?:它可以让您获取一个对象或一组对象,将它们放在磁盘上或通过有线或无线传输机制发送它们,然后稍后,也许在另一台计算机上,反转该过程:复活原始对象。基本机制是将对象展平为一维比特流,并将该比特流转回原始对象。就像《星际迷航》中的运输机,这一切都是为了把一些复杂的东西变成一个 1 和 0 的平坦序列,然后把这个 1 和 0 的序列(可能在另一个地方,可能在另一个时间)重建原来的复杂“某物。”因此,当您需要存储对象的副本、将它们发送到在同一系统上或通过网络运行的另一个进程时,请实现 Serializable 接口。因为你想存储或发送一个对象。它使存储和发送对象变得容易。它与安全无关。


为所有域模型实现 seriablizble 接口是否是最佳实践...
@theJava 这不是最佳实践的问题。这是您是否需要一系列字节的问题。
使用 JSON 时,您不必实现此接口,只需发送该字符串即可。所以我仍然不确定当您可以使用 JSON 时为什么要使用此接口。
@YonatanNir 我不确定为什么在 MsgPack、Avro、Thrift 或 Protobuf 更适合 IO 传输时使用 JSON。
@YonatanNir 严格定义的模式更好。 JSON 意味着人类可读,而二进制编码格式在网络上的效率要高得多
R
Raedwald

或许令人惊讶的是,这个问题的答案是从不,或者更现实地说,只有当您被迫与遗留代码进行互操作时。这是 Joshua Bloch 在 Effective Java, 3rd Edition 中的建议:

没有理由在您编写的任何新系统中使用 Java 序列化

Oracle's chief architect, Mark Reinhold, is on record 说移除当前的 Java 序列化机制是一个长期目标。

为什么 Java 序列化存在缺陷

Java 提供了作为语言的一部分的序列化方案,您可以通过使用 Serializable 接口选择加入。然而,这个方案有几个棘手的缺陷,Java 语言设计者应该将其视为失败的实验。

它从根本上假装人们可以谈论对象的序列化形式。但是序列化方案有无穷多,导致序列化形式无穷多。通过强加一个方案,而不用任何方式改变方案,应用程序不能使用最适合他们的方案。

它被实现为构造对象的一种附加方式,它绕过了构造函数或工厂方法执行的任何前置条件检查。除非编写了棘手、容易出错且难以测试的额外反序列化代码,否则您的代码可能存在巨大的安全漏洞。

测试不同版本的序列化表单的互操作性是非常困难的。

处理不可变对象很麻烦。

该怎么做

相反,请使用您可以显式控制的序列化方案。例如 Protocol Buffers、JSON、XML 或您自己的自定义方案。


在那个水平上不是什么专家,但觉得你说得有道理。
我认为这是最好的答案!
我们需要的答案!谢谢。
这个 Sonar 规则 rules.sonarsource.com/java/RSPEC-1948 怎么样 - 说明大多数 J2EE 框架在重负载时刷新到磁盘。对我来说听起来已经过时了,但有人知道更多吗?
到目前为止,我所知道的让您的应用程序在 Tomcat 重新启动后幸存下来的唯一方法是对存储在会话范围 bean 中的所有项目实施序列化。正确的?我可以猜想还有另一种方式,但早在几年前,那是合法的方式。
r
roottraveller

当您希望能够将类的实例转换为一系列字节时,或者当您认为 Serializable 对象可能引用您的类的实例时,请实现 Serializable 接口。当您想要持久化它们的实例或通过网络发送它们时,可序列化类很有用。 Serializable 类的实例可以很容易地传输。然而,序列化确实有一些安全后果。阅读 Joshua Bloch 的 Effective Java。