使类不可序列化的好方法是什么?

时间:2012-10-11 07:46:33

标签: java serialization coding-style

Java包含许多实现dreaded and error prone interface Serializable的类(如Swing)。

如果通过扩展TableModel来实现新的AbstractTableModel,则新模型必须是可序列化的,但如果它包含不可序列化且不需要的内部数据类型,那该怎么办?既然你不打算使用这个功能呢?

在这种情况下,像Sonar这样的工具会变得疯狂。要么抱怨“类Foo定义非瞬态非可序列化实例字段bar”。

所以我将该字段transient设为“字段Foo.bar是暂时的,但不是通过反序列化设置的”

是否可以说“不,这个类不可序列化,而且我不希望它”在Sonar这样的工具中没有出现任何错误?

5 个答案:

答案 0 :(得分:22)

引用此JavaRevisited article(参见#8):

  

为避免java序列化,您需要在Class中实现writeObject()和readObject()方法,并且需要从这些方法中抛出NotSerializableException。

所以你只需将它粘贴到你的班级中:

private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException {
    throw new java.io.NotSerializableException( getClass().getName() );
}

private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException {
    throw new java.io.NotSerializableException( getClass().getName() );
}

答案 1 :(得分:5)

实施writeObject()readObject()方法以抛出NotSerializableException

http://docs.oracle.com/javase/6/docs/platform/serialization/spec/security.html#4214

答案 2 :(得分:1)

你可以使用类似的东西吗?

@SuppressFBWarnings(justification = "This field need to be transient")
private transient SomeObject myTransientField;

您将取消Findbug警告。您还可以指定要执行的验证类型:

@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")

完整列表在那里:http://findbugs.sourceforge.net/bugDescriptions.html

答案 3 :(得分:0)

我可以考虑实施方法private void writeObject()如下:

private void writeObject(ObjectOutputStream oos) throws IOException {
    throw new UnsupportedOperationException("Not serializable!!!");
}

或者,您可以实施Externalizable并编写writeExternal()

的类似实现

两者都不是"好"方法,但只是解决方法。

答案 4 :(得分:0)

我在这里看到的答案实际上只是回答是否有可能阻止某些标记为可序列化的类的序列化或反序列化。但问题是另一个问题:

'是否可以说“不,这个类不可序列化,我不希望它”以这样的方式让你在Sonar这样的工具中没有出现任何错误?'

(所以我想知道那些答案上的那些很多票数......)

谷歌围绕答案似乎是'不',声纳可以被告知这样的课程是“误报”,但这需要修补声纳。开发由其他人的声纳检查代码的开发人员无法从这种可能性中受益。

由于这个问题实际上要求其他工具“像Sonar”的解决方案一般,答案一般不能是“是”---肯定有一些这样的工具会坚持“工具Serializable +具有不可序列化非瞬态场“意味着麻烦。