Ganesh Gudghe
Ganesh Gudghe

Reputation: 1387

Java Gson byte[] array getting converted into ArrayList

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)

Upvotes: 0

Views: 586

Answers (1)

Marcono1234
Marcono1234

Reputation: 6934

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.

Upvotes: 1

Related Questions