为啥 Java.lang.Object 不实现 Serializable 接口? [复制]

Posted

技术标签:

【中文标题】为啥 Java.lang.Object 不实现 Serializable 接口? [复制]【英文标题】:Why doesn't Java.lang.Object implement the Serializable Interface? [duplicate]为什么 Java.lang.Object 不实现 Serializable 接口? [复制] 【发布时间】:2012-07-20 23:04:54 【问题描述】:

可能重复:Why Java needs Serializable interface?

根据 Java 文档中的 Serializability :

类的可序列化性由实现 java.io.Serializable 接口。没有实现这个的类 接口不会对它们的任何状态进行序列化或反序列化。 可序列化类的所有子类型本身都是可序列化的。这 序列化接口没有方法或字段,仅用于 识别可序列化的语义

为什么对象还没有实现Serializable?我们不想被序列化的成员可以设为transient。为什么要阻止默认的 Serializability?

【问题讨论】:

This question 包含一些您可能感兴趣的好答案。 确实如此。我应该在发布之前尝试替代关键字:) 【参考方案1】:

可序列化类的所有子类型本身都是可序列化的。

换句话说:您曾经创建、曾经创建或将要创建的所有类都是可序列化的。 transient 只排除字段,不排除整个类。

这是一个潜在的安全漏洞 - 巧合的是,您可以序列化,例如您的 DataSource 内部带有数据库凭据 - 如果此特定 DataSource 实现的创建者忘记创建此类字段 transient。序列化随机 Java 对象非常容易,例如通过持有对外部this的隐式引用的内部类。

使用您明确想要并允许序列化的类的白名单比仔细检查您的代码更安全,确保没有您不想要的字段被序列化。

此外,您不能再说:MySuperSecretClass 不可序列化(通过简单地不实现 Serializable) - 您只能排除胆量(字段)。

【讨论】:

好吧,我想我完全忽略了它的安全方面。说得通。但是我们不使用 Private/Public/Protected 进行编译时访问吗?不能将瞬态或类似的东西作为运行时的任务吗?只是问问而已。还是会很麻烦。 @TJ-:恕我直言,只有一小部分类需要可序列化(值对象,DTO)。标记需要可序列化的类比标记那些不需要序列化的类要方便得多。并不是说 Java 在这方面不麻烦:恕我直言,默认情况下所有字段都应该是私有的,所有方法都应该是公共的,但是你能做什么?【参考方案2】:

1.Serializable标记接口,它是空的,但是当一个类被标记为可序列化时,意味着它的对象是可序列化的。

2. java.lang.Object 没有实现 Serializable 的原因是,如果您不想将某些字段设置为 Serializable 并且我的错误错过了向该字段添加瞬态,该怎么办?那么将是一场浩劫。

3. 通过让程序员为他的类实现 Serializable,它让程序员意识到他已经有意识地实现了它,并且应该采取必要的步骤来防止任何不应该被序列化的东西是。

【讨论】:

【参考方案3】:

大多数类不需要可序列化。使用当前的设计,您可以很容易地注意到该类是可序列化的。本质上,它只是一个经过编译器检查的自文档。否则你可能会写这样的东西:

/** DON'T SERIALIZE IT!!! */
class Connection  ... 

而且最好有语言或库的特性而不是 cmets。

【讨论】:

【参考方案4】:

我认为为需要持久化的对象实现Serializable 更有意义,而声明transiennt 类的每个字段会更麻烦。我不确定的另一点是Object 是所有类的根,其中包括与反射相关的类,因此为 Object 类实现 Serializable 是不合适的。

【讨论】:

以上是关于为啥 Java.lang.Object 不实现 Serializable 接口? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 java.lang.Object 不是抽象的? [复制]

为啥 Java 中的每个对象都隐式扩展 java.lang.Object 类?

为啥 java.lang.Object 中的 finalize() 方法是“受保护的”?

关于clone(java.lang.Object)重写

Java超类-java.lang.object

不兼容的类型:java.lang.Object 无法转换为 java.lang.String