JVM将如何处理可序列化中的默认属性?



有一个类实现Serializable,并且有一个类型为Object的属性。我通过SonarQube扫描时遇到了一个错误。它说可序列化类的属性必须是serializabletransient。所以我认为默认属性的序列化可能由jvm或容器控制。在哪里可以找到描述此机制的文章?

public class AHttpResponse implements Serializable {
private String responseCode;
private Object data; // SonarQube detect this line has `Major` problem
.....
}

此类是保存请求的结果代码和结果数据的基类。 响应将类似于前端中的以下 JSON 字符串:

{
"responseCode": "0",
"data": {
"userName":"xxx"
}
}

{
"responseCode": "0",
"data": [
{ "userName": "xxx" },
{ "userName": "yyy" }
]
}

所以,也就是说,AHttpResponsedata可以是List或JavaBean。

我认为在这种情况下不会序列化您的AHttpResponse,因此使其工作的最简单方法是使您的类不实现Serializable

public class AHttpResponse {
private String responseCode;
private Object data;
.....
}

在上面的类中,data属于Object类型,这意味着它可能是可序列化的,也可能是不可序列化的(取决于它的子类型,例如String是可序列化的,而List不是)。让我们看看javadoc对可序列化类的不可序列化属性的看法:

在反序列化期间,不可序列化类的字段将是 使用公共或受保护的 no-arg 构造函数初始化 .class。无参数构造函数必须可供子类访问 序列 化。可序列化子类的字段将被恢复 从溪流中。

由于该字段的行为从声明中不明显(即它可能可序列化也可能不可序列化),Sonarqube 会显示警告。

正如@Keijack指出的那样,Serializable与 JSON 序列化无关。

Serializable标记接口让 JVM 知道该类是可序列化的/可反序列化的,使用 Java 对象序列化机制传入/从字节流中/从字节流中序列化。

当执行类似操作时,一个使用 Java 序列化进行序列化(Jave 对象序列化规范中的示例):

// Serialize today's date to a file.
FileOutputStream f = new FileOutputStream("tmp");
ObjectOutput s = new ObjectOutputStream(f);
s.writeObject("Today");
s.writeObject(new Date());
s.flush();

如果您不打算使用 Java 序列化,只需删除Serializable接口即可。

有关 Java 对象序列化的更多详细信息,请参阅 Java 对象序列化规范。

最新更新