不必要地实施Serializable会受到什么惩罚?
我需要为我的分布式系统类开发Java RMI应用程序。
在讲座中,教授强调只让类实现Serializable ,必须通过网络传递价值。
这意味着让太多的类实现Serializable会有一些缺点或惩罚。 不需要通过网络发送的类。
我不知道如果你从未真正通过网络发送序列化/反序列化将永远不会发生任何缺点。
不必要地实施Serializable会受到什么惩罚?
不必要地实施Serializable
不会受到惩罚。 如果你从不序列化对象,那么因为你添加了可implements Serializable
,没有任何反应。 如果你对它进行序列化,它可以工作而不是失败。 那不是惩罚。
为什么教授强调这是一个谜。 问他。 除了序列化之外没有任何开销,如果你通过RMI按值传递对象, 除了实现Serializable
别无选择,所以没有什么可以评估开销。 这毫无意义。
只允许类实现必须通过网络传递值的Serializable。
您的教授建议您尽量减少使用Serializable
到严格需要的区域。
这是因为序列化是泄漏实现的有力候选者 。 实现Serializable
显示了序列Serializable
意图(即使对象从未实际被序列化),这强加了开发人员在修改这些类时要小心以避免破坏软件的想法。
Joshua Bloch在他的“ Effective Java”一书中介绍了这一点。
序列化对象的那一刻,如果没有特殊处理,就无法再修改它实例化的类† 。 如果修改类,则二进制表示将不再与已序列化的对象匹配。 因此,在修改类之前序列化的任何对象的反序列化将失败。
如果类型实现Serializable
,则它有可能被序列化。 如果序列化了该类型的实例,则可以通过修改代码的实现来中断代码。
由于没有简单的方法可以确定序列化类型的实例已被序列化(尽管您可能不打算将对象序列化),开发人员在修改这些类型的实现时会非常谨慎。
† – 通过正确版本化可序列化类型可以避免这种情况,但由于版本控制没有合同更改的类型(没有编译时error handling支持通知您),最好保持显式版本最小化以避免添加您的设计过于复杂 。
我会理解教授的“只允许类实现 Serializable,必须通过网络传递值”不同。 我认为这个想法是,如果你必须以这种方式使用一个类,那么自己实现writeObject,readObject和readObjectNoData,这可能比默认实现更有效。
如果有人后来想要对可序列化类进行子类化,那么他们必须确保他们的类确实可以序列化。 这可能需要他们不想做的努力。
说你有:
public class YourClass implements Serializable { }
现在,如果我写:
class MyClass extends YourClass { private SomeoneElsesClass myField; }
而且SomeoneElsesClass
不可序列化,我的FindBugs将使用消息“可序列化类中的非瞬态非可序列化实例字段”标记myField
。 我试图保持我的代码清除警告消息,但在这种情况下,我不能。
我经常专攻Swing课程。 有时我想拥有非可序列化类的实例字段,这基本上会在我的代码中引入错误。 在现实生活中,我只收到一条警告信息,只要该对象实际上没有被序列化,它就会起作用; 我仍然对这些警告信息感到恼火。