目录
场景
新加的一个类使用findbugs扫描提示SE_BAD_FIELD序列化错误, 使用FindBugsFilter过滤也无效,以下是具体信息:
[INFO] Total bugs: 1
[INFO] Class com.xx.xx.xxx.$Context defines non-transient non-serializable instance field excelTempFileOutputStream [com.xx.xx.xxx.$Context] In ExportUtil.java SE_BAD_FIELD
[INFO]
To see bug detail using the Findbugs GUI, use the following command "mvn findbugs:gui"
根据提示应该是outputStream的问题试了下FindBugsFilter过滤MyTest 这个类结果未生效
示例代码
public class MyTest implements Serializable {
// 这个变量会提示defines non-transient non-serializable instance field outputStream
private FileOutputStream outputStream;
}
解决
方案1, 给属性加上transient关键字,该字段将不会被序列化保存和恢复
transient Java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程。
public class MyTest implements Serializable {
private transient FileOutputStream outputStream;
}
再次运行检查,成功
2,实现Externalizable接口代替Serializable接口,对序列化过程进行完全自主控制。
Externalizable没有默认序列化机制,我们需要在writeExternal()方法中将希望被序列化的对象的信息写入,在readExternal()中将其恢复,并且writeObject()方法与readObject()方法中保存和恢复对象的顺序必须相同。
扩展
应该是FileOutputStream对象没有序列化, 当它作为类变量时也不能序列化, 查看了下FileOutputStream对象的源码, 确实没有序列化, 这里验证下
import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import java.io.Serializable; /** * @author ys * @version 1.0 * @date 2023/06/27 14:09 */ public class Test { @Getter @Setter @ToString @NoArgsConstructor private static class Context implements Serializable { /** * serialVersionUID:序列化ID */ private static final long serialVersionUID = 1L; String id; User user; } @Getter @Setter @ToString static class User { String name; } }
上述代码中User类未序列化, 运行findbugs, 果然重现
修改User类, 再次运行findbugs, 显示: FindBugs-IDEA: Analysis Finished Found 0 bugs
@Getter @Setter @ToString static class User implements Serializable { /** * serialVersionUID:序列化ID */ private static final long serialVersionUID = 1L; String name; }
其他
自动找Bug/插件-代码静态检查findbugs-idea安装以及使用_idea findbugs插件_瑶山的博客-CSDN博客