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

ObjectTypeAdapter error when the value type is a Number #1257

Closed
marcgise opened this issue Feb 21, 2018 · 4 comments
Closed

ObjectTypeAdapter error when the value type is a Number #1257

marcgise opened this issue Feb 21, 2018 · 4 comments

Comments

@marcgise
Copy link

Hi,
I found an error in the read method of the ObjectTypeAdapter when the value is a Number, as it always transforms it to a double value. But maybe the expected value is an Integer. I made the following change, and it seems to work fine:

switch (token) {
    case NUMBER:
        String value = in.nextString();
        if (value.contains(",") || value.contains(".")) {
            return new BigDecimal(value); // or Double.valueOf(value);
        } else {
            return Integer.valueOf(value);
        }
    case....:
}
@marcgise
Copy link
Author

Another error I found, is that the ObjectTypeAdapter could not be overriden: neither by extending the class (because it's final) nor by adding another factory to the Gson, because ObjectTypeAdapter is always processed first.

@zenglian
Copy link
Contributor

zenglian commented Apr 1, 2018

Gson team is aware of that since its 1st version (9 Sep 2011).

@SiemelNaran
Copy link

Maybe we don't want people to be able to override ObjectTypeAdapter or put it second in the list of factories as it could change the default behavior of parsing JSON objects. But can we try out the following way of customizing the behavior of ObjectTypeAdapter? That is, change the following code:

    case NUMBER:
      return in.nextDouble();

to

    case NUMBER:
      return numberReader.read(in);

And there will be a new function in GsonBuilder like registerObjectNumberReader(NumberReader). The default NumberReader will just call in.nextDouble(). But the new one will have functions/enums to prefer BigInteger, long, int, or short when the token is an integer type, and similar stuff for float types. This is similar to Jackson's DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS.

Would this work? I can work on this.

Another thing I'd like is to ability to force types based on the path. For example, when parsing { "finance": { "cost": 23000 }}, we could specify that $.finance.cost is always a BigDecimal. By looking at the value of in.getPath() in the debugger, it does not look to be right. For example in { "cost": 23000 } the path is "$." when reading 23000 but I want "$.cost". In { "finance":{ "cost": 23000 }} the path is "$..cost" but I 'd like "$.finance.cost".

@eamonnmcmanus
Copy link
Member

Fixed by #1290.

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

4 participants