Gson: Double cannot be casted to Integer.

Created on 31 Aug 2015  Â·  23Comments  Â·  Source: google/gson

Long cannot be casted to Integer, Integer cannot be casted to Short, etc. Could you fix it in https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/bind/ObjectTypeAdapter.java? When serializing Map<String, Object> and deserializing, it throws Exception. I can't edit this, because I can't edit Spigot/Bukkit. If JSON save Integer, it should read Integer, not make Double unnecessarily.

I maked it in issue, because I had to download sources GSON and edit this:.

    case NUMBER:
      try {
        return in.nextInt();
      } catch(NumberFormatException exception) {
      }
      try {
        return in.nextLong();
      } catch(NumberFormatException exception) {
      }
      return in.nextDouble();

Most helpful comment

Could the convention be that anything missing a . is an integer and anything with a . is a double?

All 23 comments

@swankjesse In our original parser, I tried to convert any number to its smallest form first. So, first see if it fits in short, int and long, then try double.
Any reason why we should convert it to double by default?

I wrote, that serializing and deserializing Object doesn't work correctly. Try serialize Integer number, then deserialize it as fromJson(..., Object.class). It will return double. Why double, not Integer?

I think that it should convert it default to integer, no double. Integer can be casted to double, but double cannot be casted to Integer.

It may be because of routine, which converts all numbers to double.
case NUMBER:
return in.nextDouble();

Double by default is the best for simplicity. Things like equals() break if we use a mix of different types here.

@swankjesse It is definitely not the best. Crucial difference is double is a floating point. Right now gson is forcing any numerical value to have fractional part. There's no integers support. Which is ridiculous.

There's int support, as long as you provide the target type. When you ask Gson to decode an object without a target type, it needs a policy and Gson’s policy is to be consistent with JavaScript.

(Arguing int vs. double is particularly awkward because there's no data loss.)

Double cannot be casted to Integer. I have Object in main app and plugin
that using Gson cannot modify it. It will throw Exception, so I can't use
it in plugins.
7 paź 2015 14:16 "Jesse Wilson" [email protected] napisaÅ‚(a):

(Arguing int vs. double is particularly awkward because there's no data
loss.)

—
Reply to this email directly or view it on GitHub
https://github.com/google/gson/issues/692#issuecomment-146179250.

@swankjesse Why there's should be data loss? If value has "." ({rating: 3.4}) , it can be parsed to double, if not - into long ({comments: 15}).

@swankjesse I do understand you stand for simplicity. But treating numeric without floating point as a numeric with floating point has a serious impact on business logic. There's not much difference between Integer and Long from business logic point of view, but difference between Long and Double is huge. ({comments: 15.0}, anyone?). Current implementation is making things either unusable for serious tasks (having no proper integer support) or overly complicated (writing own IntegerAwareObjectAdapter). Serializing/deserializing Properties, for example, is a pain.

Why are you decoding it as Object?

Ie. if you want type safety, provide the types!

But I don't know, what's type is it. I need Object, which can be Integer.
7 paź 2015 20:00 "Jesse Wilson" [email protected] napisaÅ‚(a):

Ie. if you want type safety, provide the types!

—
Reply to this email directly or view it on GitHub
https://github.com/google/gson/issues/692#issuecomment-146278854.

@swankjesse I'm deserializing it as a Map (and it is actually a map).
And it is not about type safety, it is about using most specific type. Java was built that way - when dealing with polymorphism, most specific type is considered.

@swankjesse: I'm afraid you do not understand my problem with Properties. I'm providing the types when serializing it, and gson correctly serializes integers as integers. But when I'm deserializing my Properties back (let's say, from json received from server), all integers are becoming doubles, and that's breaking a lot of things. I have to check every entry which I expect to be integer and convert it from double to integer. This particular method we're talking about is meant to deserialize maps, and it is definitely broken, as it considers any number in map being a floating point. Using most specific type instead of most generic type is more correct, imho.

Could the convention be that anything missing a . is an integer and anything with a . is a double?

@oleersoy: yup, I'm using exactly that logic in my custom adapter.

I think you want to decode it as a Map<String, Integer>. No action to take here.

No. Some keys is String, some Double, some Float, some Map. Map is parsed
by Bukkit for ItemStack, so I can't modify it.
7 paź 2015 22:14 "Jesse Wilson" [email protected] napisaÅ‚(a):

I think you want to decode it as a Map. No action to
take here.

—
Reply to this email directly or view it on GitHub
https://github.com/google/gson/issues/692#issuecomment-146315171.

Values*

It may be check while converting string to number:

if (number . contains( "." ) || number . contains( "e" ) || number . contains( "E" )) {
return Double . valueOf(number);
} else {
return Long . valueOf(number);
}

Or:

  try {
    return in.nextInt();
  } catch(NumberFormatException exception) {
  }
  try {
    return in.nextLong();
  } catch(NumberFormatException exception) {
  }
  return in.nextDouble();

Is there a way to override this behavior?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GoogleCodeExporter picture GoogleCodeExporter  Â·  15Comments

GoogleCodeExporter picture GoogleCodeExporter  Â·  31Comments

LucianWang picture LucianWang  Â·  42Comments

JakeWharton picture JakeWharton  Â·  39Comments

GoogleCodeExporter picture GoogleCodeExporter  Â·  14Comments