我正在使用 Gson 进行对象序列化和反序列化,但是 Gson 将 byte[] 数组转换为 ArrayList
对象类别
public class RequesterArgument implements Serializable {
private Object data;
public void setData(Object data) {
this.data = data;
}
public Object getData() {
return data;
}
}
我有一个对象数组[]
byte[] data = {74,97,118,97,73,110,85,115,101};
现在我将这个 byte[] 设置为我的对象
byte[] data = {74,97,118,97,73,110,85,115,101};
RequesterArgument request = new RequesterArgument();
request.setData(data);
System.out.println(request.getData().getClass().getName());
现在输出是 [B byte
但是如果我将它转换为 JSON 字符串
String jsonString = new Gson().toJson(request);
再次尝试将其转换为实际对象
RequesterArgument response = new Gson().fromJson(jsonString, RequesterArgument.class);
System.out.println(response.getData().getClass().getName());
如果我尝试打印类名,它不会给我 java.util.ArrayList 类型
那么有什么方法可以避免类型转换(如果我将对象数据更改为 byte[] 数据那么它工作正常)无需更改实际类型?
Gson 将字节数组序列化和反序列化为 JSON 数组。这就是您在响应中获得 ArrayList 的原因。如果你不想要这种行为,你可以为 byte[] 类型编写一个自定义的 JsonSerializer 和 JsonDeserializer。
那么有没有办法避免类型转换
不,至少不是你当前的代码。 Gson 将 Java 数组序列化为 JSON 数组。在反序列化时,Gson 只知道字段类型是
Object
并识别出 JSON 数据包含一个由 JSON 数字组成的 JSON 数组。在这种情况下,它将数据反序列化为List<Double>
(或更具体地说是ArrayList<Double>
)。
最干净的解决方案可能是为
RequesterArgument
添加一个类型参数,代表data
的类型:
public class RequesterArgument<T> {
private T data;
...
}
主要区别在于,当您现在使用
Gson.fromJson
时,您必须提供一个 TypeToken
来指定 T
的实际参数(另请参阅 User Guide):
TypeToken<RequesterArgument<byte[]>> typeToken = new TypeToken<RequesterArgument<byte[]>>() {};
RequesterArgument<byte[]> response = new Gson().fromJson(jsonString, typeToken);
(注意:较旧的 Gson 版本需要您调用
typeToken.getType()
)
@JsonAdapter
注释,它指的是自定义 TypeAdapterFactory
其适配器查看 JSON 数据,然后根据类型尝试将其反序列化为byte[]
.
此外,作为旁注,Gson 不要求您的类实现
Serializable
。并且为了避免误会,Gson没有使用getters和setters,它直接修改字段值。尽管您当然可以让自己的代码调用 getter 和 setter。