19

Java 包含许多实现可怕且容易出错的 接口Serializable的类(如 Swing 中的类) 。

例如,如果您TableModel通过扩展实现 new AbstractTableModel,则新模型必须是可序列化的,但如果它包含不可序列化的内部数据类型,并且由于您不打算使用此功能而不必序列化,该怎么办?

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

所以我制作那个字段transient只是为了得到“该字段Foo.bar是瞬态的,但不是由反序列化设置的”

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

4

5 回答 5

25

引用这篇JavaRevisited 文章(参见 #8):

为避免 java 序列化,您需要在类中实现 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() );
}
于 2012-10-11T07:49:46.073 回答
6

实现writeObject()readObject()抛出的方法NotSerializableException

或者

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

于 2012-10-11T07:50:45.450 回答
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

于 2015-11-18T21:52:43.210 回答
0

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

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

(所以我想知道那些答案有那么多赞成票......)

谷歌搜索的答案似乎是否定的,Sonar 可以被告知这样的类是“误报”,但这需要对 Sonar 进行修补。开发由其他人的 Sonar 检查的代码的开发人员无法从这种可能性中受益。

而且由于这个问题实际上也要求为“像 Sonar”之类的其他工具提供解决方案,所以一般的答案不能是“是”——当然,一些这样的工具会坚持“实现 Serializable + 具有不可序列化的非瞬态字段"的意思是麻烦。

于 2012-10-11T08:23:54.933 回答
0

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

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

或者,您可以实现Externalizable并编写类似的实现writeExternal()

两者都不是“好”的方法,而只是解决方法。

于 2012-10-11T07:53:19.800 回答