通过序列化/ GSON将对象自动转换为双精度 [英] Object Autoconvert to Double with Serialization/GSON

查看:167
本文介绍了通过序列化/ GSON将对象自动转换为双精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开发使用Gson序列化对象并反序列化它们的应用程序时,我遇到了一个问题。然而,我遇到了一个问题,我无法解释原因,过了一段时间,我将问题缩小到了这个SSCCE:

  import com.google.gson.Gson; 
$ b / **
*显示手边的问题
* /
公共类Probs {
public Probs(){
//保存JSON数据的字节数组形式
byte [] info = new byte [1];

//获取数据对象的JSON并将其存储在字节数组中
Gson gson = new Gson();
之前的数据=新数据(1);
info = gson.toJson(before).getBytes();

//以字符串形式重新组合JSON数据
String json = new String(info);
System.out.println(JSON string:+ json);

//从JSON数据重建数据对象
数据在= gson.fromJson(json,Data.class)之后;

//尝试获取num值并将其转换为整数
Object val = after.getNum();
System.out.println(Class name:+ val.getClass()。getName()); //为java.lang.Double(为什么不是java.lang.Object?)
Integer num =(Integer)val; //产生java.lang.ClassCastException:java.lang.Double不能转换为java.lang.Integer
System.out.println(Number:+ num);


public static void main(String [] args){
new Probs();
}
}

/ **
*保存一条数据
* /
class Data {
Object NUM;
public Data(int num){
this.num = num;
System.out.println(Object value:+ this.num);
}

public Object getNum(){
return this.num;
}
}

我读过这篇文章,但它似乎并没有有任何接受的答案。由于我在应用程序中使用它的方式,我需要让Data对象将其数据存储为对象,并且能够稍后将其转换为其他类型。当我反序列化数据对象并调用它的getNum()时,我认为应该返回一个Object(因为这是它的返回类型)。在我的应用程序中,我需要能够将该类型转换为Integer。但是,JVM似乎将Object(val)转换为Double,因为getClass()显示它是Double而不是Object。然后,当我尝试通过转换将其转换为整数时,它会失败,因为它显然是Double而不是Object。



我的问题是:为什么是val Double而不是一个对象(我不明白什么)?



感谢您的帮助

解决方案

这个问题是JSON规范,以及你在做什么。



JSON规范仅指定一个单个数字类型,可以包含小数点和小数部分:


2.4。数字

数字的表示与大多数的
编程语言中使用的相似。一个数字包含一个整数部分,可以在

前面加上一个可选的减号,后面可以跟着
a小数部分和/或指数部分。


JSON解析器需要自己决定在解析/映射JSON时如何处理该数字类型。



在你的情况下,你的 Data 类将 num 定义为 Object 。这让Gson无法知道您希望将JSON数字类型映射到哪种特定的Java数字类型。 Gson的作者在这种情况下决定使用 Double ,而不管JSON中的数字是否包含小数+分数。

当你认为一个整数可以表示为双精度时,这实际上是非常有意义的,而不是相反。使用单一类型而不是解析数字并判断它是int还是double会提供一致的行为。



目前还不清楚为什么不使用数据中为 num >整数(或 int ) 对象,如果这是你所期望/需要的。你声明你需要转换为 Integer later,这意味着对象首先可以放在 Integer ;其他任何投射尝试都会失败。

I ran into a problem when developing an application that uses Gson to serialize objects and deserialize them. However, I ran into a problem that I cannot explain the cause of 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 did read this post but it did not appear to have any accepted answers. Because of the way I use it in my application, I need to have the Data object store its data as an Object and be able to cast it later to a different type. When I deserialize the data object and call its getNum(), I thought that should return an Object (since that is its return type). In my application, I need to be able to convert that type into an Integer. However, the JVM appears to convert the Object (val) into a Double because the getClass() reveals that it is a Double and not an Object. Then when I try to convert it to an integer via a cast it fails because it is apparently a Double and not an Object.

My question is: why is val a Double and not an Object (what am I not understanding)?

Thank you for your help

解决方案

The issue is the JSON spec, and what you're doing.

The JSON spec only specifies a single numeric type, which can a include a decimal point and a fractional portion:

2.4. Numbers

The representation of numbers is similar to that used in most
programming languages. A number contains an integer component that
may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part.

JSON parsers are left to decide for themselves what to do with that numeric type when parsing/mapping the JSON.

In your case, your Data class has num defined as Object. This gives Gson no hint as to what specific Java numeric type you'd like the JSON numeric type mapped to. The authors of Gson decided to use a Double when this is the case regardless of whether the number in the JSON includes a decimal + fraction or not.

This actually makes perfect sense when you consider that an integer can be expressed as a double, but not the other way around. Using a single type rather than parsing the number and deciding if it's a int or a double provides consistent behavior.

It's unclear why you aren't using Integer (or int) for num in your Data object if that's what you expect/need. You state you need to cast to Integer "later" which means the only thing that object can be in the first place is an Integer; any other casting attempt would fail.

这篇关于通过序列化/ GSON将对象自动转换为双精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆