Koo*_*inn 53 java serialization findbugs
考虑下面的课程.如果我针对它运行Findbugs,它将在第5行给出一个错误("可序列化类中的非瞬态非可序列化实例字段")但不在第7行.
1 public class TestClass implements Serializable {
2
3 private static final long serialVersionUID = 1905162041950251407L;
4
5 private Set<Integer> mySet; // Findbugs error
6
7 private HashSet<Integer> myOtherSet;
8
9 }
Run Code Online (Sandbox Code Playgroud)
这是正确的,因为java.util.Set从不在其层次结构中实现Serializable,而java.util.HashSet也是如此.但是,最佳做法是针对接口而不是具体实现进行编码.
我怎样才能最好地处理这件事?
我可以在第3行添加@Suppresswarnings(justification ="No bug",values ="SE_BAD_FIELD").我的实际代码中有很多集合和列表,我担心它会丢失我的代码太多.
还有更好的方法吗?
Mic*_*rdt 28
但是,最佳做法是针对接口而不是具体实现进行编码.
我提出不,在这种情况下不是.Findbugs非常正确地告诉您,只要您在该字段中NotSerializableException具有非可序列化的Set实现,就会冒险进入.这是你应该处理的事情.怎么样,这取决于你的课程的设计.
Serializable.为此,请创建一个界面SerializableSet extends Set, Serializable并将其用于您的领域.然后,要么:
SerializableSet公共接口,并提供实现它的实现类.instanceof Serializable,如果不是,则将它们复制到类似的东西中.小智 12
我知道这是一个已经回答的旧问题,但其他人知道,Set<Integer>如果您对序列化特定字段没有兴趣可以修复FindBugs错误,则可以将字段设置为瞬态.
public class TestClass implements Serializable {
private static final long serialVersionUID = 1905162041950251407L;
private transient Set<Integer> mySet;
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢这种方法,而不是强迫你的API用户强制转换为你的具体类型,除非它只是内部的,然后Michael Borgwardt的回答更有意义.
您可以Critical通过向您的类添加以下方法来消除这些警告消息:
private void writeObject(ObjectOutputStream stream)
throws IOException {
stream.defaultWriteObject();
}
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
}
Run Code Online (Sandbox Code Playgroud)
您可以使用捕获帮助程序来确保传入的Set支持两个接口:
private static class SerializableTestClass<T extends Set<?> & Serializable> implements Serializable
{
private static final long serialVersionUID = 1L;
private final T serializableSet;
private SerializableTestClass(T serializableSet)
{
this.serializableSet = serializableSet;
}
}
public static class PublicApiTestClass
{
public static <T extends Set<?> & Serializable> Serializable forSerializableSet(T set)
{
return new SerializableTestClass<T>(set);
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以拥有一个强制Serializable的公共API,而无需检查/需要特定的实现细节.
我使用findbugs-exclude过滤器来收集字段:
<Match>
<Field type="java.util.Map" />
<Bug pattern="SE_BAD_FIELD" />
</Match>
<Match>
<Field type="java.util.Set" />
<Bug pattern="SE_BAD_FIELD" />
</Match>
<Match>
<Field type="java.util.List" />
<Bug pattern="SE_BAD_FIELD" />
</Match>
Run Code Online (Sandbox Code Playgroud)
见http://findbugs.sourceforge.net/manual/filter.html
| 归档时间: |
|
| 查看次数: |
61188 次 |
| 最近记录: |