catekr / json-simple

Automatically exported from code.google.com/p/json-simple
Apache License 2.0
0 stars 0 forks source link

Ordinal number type inequality after deserialization #64

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create a JSONObject with byte, short, int key/value pairs.
2. Create a new JSONObject with the string from the first JSONObject
3. Compare them with .equals

What is the expected output? What do you see instead?

I expect equals to return true. 

What version of the product are you using? On what operating system?

Json-Simple V1.1 on JRE 1.6.29 on Windows 7.

Please provide any additional information below.

It fails because on the first object, the native specified types are honored in 
the map (byte, short, int).  But after being loaded from the JSON string, all 
of the ordinal values are (long).  So the equals in the Map comparison checks 
the classes and the Byte.class is not equals to Long.class so it fails even 
though numerically the values are the same.  I have a wrapper class for 
JSONObject and worked around the problem like this:

if (value instanceof Float) {
            asMap(jsonObject).put(key, ((Number)value).doubleValue());
        } else if (value instanceof Double) {
            asMap(jsonObject).put(key, ((Number)value).doubleValue());
        } else if (value instanceof Number) {
            asMap(jsonObject).put(key, ((Number)value).longValue());
        } else {
            asMap(jsonObject).put(key, value);
        }

Original issue reported on code.google.com by shea...@gmail.com on 19 Jan 2012 at 5:32

GoogleCodeExporter commented 8 years ago
It's not guaranteed to be equal: some meta info such as data type will be lost 
when serializing Java Object to JSON literal. For example, if we have a 
java.lang.Long with value 123, when generating JSON, it will output the value 
123 itself without any type info, now if we want to read it back to Java 
object, we have no way to know if we should make it a Long or an Integer. 

Original comment by fangyid...@gmail.com on 21 Feb 2012 at 5:32

GoogleCodeExporter commented 8 years ago
Right but that's why I normalized it on the way in.  You have to pick a type 
(longs and doubles it seems) when you are deserializing, may as well normalize 
the numbers on the way in to match their deserialized counterparts.

Original comment by she...@zaxasoft.com on 21 Feb 2012 at 5:35

GoogleCodeExporter commented 8 years ago
If the value of an int or short or long is 123, the value stored in JSON is 
"123". While you have insufficient information to return the value "123" as an 
int rather than long, you can determine that the converted values are 
identical.  

The Map comparison should not check the Java objects, but rather the JSON 
ordinal values to be compared.

Original comment by mcv...@gmail.com on 21 Feb 2012 at 5:52

GoogleCodeExporter commented 8 years ago
Well, I accept it as an enhancement to override the "equals" of JSONObject to 
make it compare values instead of objects, if it's the case of this request.

Original comment by fangyid...@gmail.com on 21 Feb 2012 at 11:45

GoogleCodeExporter commented 8 years ago
That would definitely help. Thanks!

Original comment by she...@zaxasoft.com on 22 Feb 2012 at 3:30