Autoconvert to Double Object with Serialization / GSON

I had a problem developing an application that uses Gson to serialize objects and deserialize them. However, I had a problem due to which I cannot explain the reason and after a while, I narrowed down the problem to this SSCCE:

import com.google.gson.Gson; /** * demonstrates the issue at hand */ public class Probs { public Probs () { //holds the byte array form of the JSON data byte[] info = new byte[1]; //get the JSON for a data object and store it in the byte array Gson gson = new Gson(); Data before = new Data(1); info = gson.toJson(before).getBytes(); //reassemble the JSON data as a string String json = new String(info); System.out.println("JSON string: " + json); //reconstruct the Data object from the JSON data Data after = gson.fromJson(json, Data.class); //attempt to get the "num" value and convert it to an integer Object val = after.getNum(); System.out.println("Class name: " + val.getClass().getName()); //is java.lang.Double (why isn't it java.lang.Object?) Integer num = (Integer)val; //produces "java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer" System.out.println("Number: " + num); } public static void main(String[] args) { new Probs(); } } /** * holds the one piece of data */ class Data { Object num; public Data(int num) { this.num = num; System.out.println("Object value: " + this.num); } public Object getNum () { return this.num; } } 

I read this post , but it did not have any accepted answers. Due to the way I use it in my application, I need the Data object to store its data as an object and can subsequently translate it to another type. When I deserialize the data object and call its getNum (), I thought I should return an Object (since this is its return type). In my application, I need to convert this type to Integer. However, the JVM seems to convert Object (val) to Double, because getClass () shows that it is Double, not Object. Then, when I try to convert it to an integer using a cast, it fails because it appears to be a Double and not an Object.

My question is: why val a Double and not Object (which I don't understand)?

thanks for the help

0
source share
1 answer

The problem is the JSON specification and what you are doing.

The JSON specification specifies only one numeric type, which can include a decimal point and a fractional part:

2.4. The numbers

The representation of numbers is similar to the representation used in most cases by programming languages. The number contains an integer component, which may have a prefix with an optional minus sign, followed by part of the fraction and / or exponential part.

JSON parsers are left to decide for themselves what to do with this number type when parsing / matching JSON.

In your case, your Data class has num defined as Object . This gives Gson no clue as to which specific type of Java type you need to display a numeric JSON type. Gson authors decided to use Double when this happens, regardless of whether the number in JSON includes decimal + fraction or not.

This really makes sense when you consider that an integer can be expressed as a double, but not vice versa. Using one type, not parsing a number and deciding whether int or double supports consistent behavior.

It is not clear why you are not using Integer (or int ) for num in your Data object, if that is what you expect / need. You declare that you need to send to Integer "later", which means the only thing that the object can be in the first place - Integer ; any other casting attempt will fail.

+2
source

Source: https://habr.com/ru/post/1246737/