Java Gson将byte[]数组转换为ArrayList

huangapple go评论71阅读模式
英文:

Java Gson byte[] array getting converted into ArrayList

问题

我正在使用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类型

所以有没有办法在不更改实际类型的情况下避免类型转换?
注意:(如果我将Object data更改为byte[] data,那么它将正常工作)

英文:

I am using Gson for object serialization and deserialization but Gson converts byte[] array to ArrayList

Object class

public class RequesterArgument implements Serializable {

 private Object data;
 
     public void setData(Object data) {
        this.data = data;
    }

    public Object getData() {
        return data;
    }
	
}

And I have an object array[]

byte[] data = {74,97,118,97,73,110,85,115,101};

now i am setting this byte[] to my object

    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());

now the output is [B byte

but if I convert it to a JSON string

String jsonString = new Gson().toJson(request);

and again try to convert it to the Actual object

RequesterArgument response = new Gson().fromJson(jsonString, RequesterArgument.class);

System.out.println(response.getData().getClass().getName());

and if I try to print the class name not it is giving me the java.util.ArrayList type

So is there any way to avoid type conversion without changing the actual type?
Note: (if I change Object data to a byte[] data then it is working fine)

答案1

得分: 1

> 是否有任何方法可以避免类型转换

不好意思,至少不使用您当前的代码。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的实际参数(还请参阅用户指南):

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不使用getter和setter,它直接修改字段的值。当然,您也可以让您自己的代码调用getter和setter。

英文:

> So is there any way to avoid type conversion

No, at least not with your current code. Gson serializes Java arrays as JSON arrays. On deserialization Gson only knows that the field type is Object and recognizes that the JSON data contains a JSON array consisting of JSON numbers. In that case it deserializes the data as List<Double> (or more specifically ArrayList<Double>).

The cleanest solution might be to add a type parameter to RequesterArgument, representing the type of data:

public class RequesterArgument<T> {
    private T data;

    ...
}

The main difference is that when you now use Gson.fromJson, you have to provide a TypeToken which specifies the actual argument for T (see also the User Guide):

TypeToken<RequesterArgument<byte[]>> typeToken = new TypeToken<RequesterArgument<byte[]>>() {};

RequesterArgument<byte[]> response = new Gson().fromJson(jsonString, typeToken);

(Note: Older Gson versions require that you call typeToken.getType())

If that solution is not possible for you, another option would be to add a @JsonAdapter annotation to the field, which refers to a custom TypeAdapterFactory whose adapter peeks at the JSON data and then depending on the type tries to deserialize it as byte[].

Also, as side note Gson does not require that your classes implement Serializable. And also to avoid any misunderstandings, Gson does not use getters and setters, it directly modifies the field value. Though you can of course let your own code call the getters and setters.

huangapple
  • 本文由 发表于 2023年3月31日 21:02:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75898865.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定