Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double cannot be casted to Integer. #692

Closed
adiantek opened this issue Aug 31, 2015 · 23 comments
Closed

Double cannot be casted to Integer. #692

adiantek opened this issue Aug 31, 2015 · 23 comments

Comments

@adiantek
Copy link

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();
@inder123
Copy link
Collaborator

inder123 commented Sep 1, 2015

@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?

@adiantek
Copy link
Author

adiantek commented Sep 1, 2015

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.

@javadev
Copy link

javadev commented Oct 7, 2015

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

@swankjesse
Copy link
Collaborator

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

@ai212983
Copy link

ai212983 commented Oct 7, 2015

@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.

@swankjesse
Copy link
Collaborator

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.

@swankjesse
Copy link
Collaborator

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

@adiantek
Copy link
Author

adiantek commented Oct 7, 2015

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" notifications@github.com 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
#692 (comment).

@ai212983
Copy link

ai212983 commented Oct 7, 2015

@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}).

@ai212983
Copy link

ai212983 commented Oct 7, 2015

@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.

@swankjesse
Copy link
Collaborator

Why are you decoding it as Object?

@swankjesse
Copy link
Collaborator

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

@adiantek
Copy link
Author

adiantek commented Oct 7, 2015

But I don't know, what's type is it. I need Object, which can be Integer.
7 paź 2015 20:00 "Jesse Wilson" notifications@github.com napisał(a):

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


Reply to this email directly or view it on GitHub
#692 (comment).

@ai212983
Copy link

ai212983 commented Oct 7, 2015

@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.

@ai212983
Copy link

ai212983 commented Oct 7, 2015

@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.

@oleersoy
Copy link

oleersoy commented Oct 7, 2015

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

@ai212983
Copy link

ai212983 commented Oct 7, 2015

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

@swankjesse
Copy link
Collaborator

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

@adiantek
Copy link
Author

adiantek commented Oct 7, 2015

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" notifications@github.com napisał(a):

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


Reply to this email directly or view it on GitHub
#692 (comment).

@adiantek
Copy link
Author

adiantek commented Oct 7, 2015

Values*

@javadev
Copy link

javadev commented Oct 7, 2015

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

@adiantek
Copy link
Author

adiantek commented Oct 7, 2015

Or:

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

@iamMehedi
Copy link

Is there a way to override this behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants