我会定义serialVersionUID。虽然这个对象可能永远不会被序列化,但是确保它的serialVersionUID是一个良好的做法,因为它可以防止未来的问题。另外,添加@SuppressWarnings注释只是掩盖了这个警告,而没有解决潜在的序列化问题。
我不懂Java的最佳实践,但是如果你声称不会进行序列化,可以添加一个抛出异常的writeObject方法,然后抑制警告,确信它不可能适用于你。
否则,未来某个人可能会通过父类对您的对象进行序列化,并以默认序列化形式结束:
添加ID听起来像是一个补救措施,因为你真正想做的是不要序列化。期望调用方不要序列化您的对象意味着您期望他们“知道”何时使用您的类的HttpServlet。这种违反多态性的行为是因为您拥有一个不能被序列化的可序列化对象,而您至少可以确保不谨慎的调用者知道它。
我拒绝被Eclipse恐吓,不让它向我的代码中添加混乱!
我刚刚配置了Eclipse,使其不会因缺少serialVersionUID而产生警告。
感谢@Steve Jessop提供的答案。只需要五行代码...完全没有麻烦。
我在相关的类之前添加了@SuppressWarnings("serial")
。
我还添加了这个方法:
private void writeObject(ObjectOutputStream oos) throws IOException {
throw new IOException("This class is NOT serializable.");
}
希望那就是 Steve 所指的 :)
对于实现可序列化的每个类,生成SVUID是一个好习惯。原因很简单。您永远无法知道何时将由您或第三方对其进行序列化。可能配置了许多服务来序列化servlet。对于每个IDE都存在生成器插件,只需使用模板并设置svuid = 1L即可。
这要看情况。
如果您使用不同的编译器多次编译源代码,那么编译后的代码可能具有不同的序列化ID,这将导致序列化失败。然后,您需要在代码中明确地坚持使用一个常量序列化ID。它必须是静态和final的,并且每个类(不可继承)。
然而,如果您始终使用特定的编译器编译代码,并始终一次性部署所有VMs上的代码,则可能需要严格的版本检查,并希望确保任何时候只运行一个版本的代码,在这种情况下,您应该只是抑制警告。因此,如果某个VM未能成功部署并运行旧版本的代码,则您可能期望在序列化期间出现异常,而不是奇怪的反序列化对象。这恰好是我的情况,我们曾经拥有一个非常庞大的集群,我们需要严格的版本检查来发现任何部署问题。
无论如何,可能应尽可能避免序列化,因为与协议缓冲区或thrift相比,默认序列化速度非常慢,并且不支持跨语言互操作性。
1L
还是一些生成的ID),那么每当需要兼容性更改时,你就要承担更新该ID的负担,以使事情正常运行。它们基本上就像库版本,但在类级别上。指定一个ID然后从不更改它比不指定它要有害得多。(更不用说在writeObject
中抛出异常,这将成为我预测的维护噩梦)。 - Stijn de Witt
serialVersionUID
。 - user207421