New issue 64 by shea...@gmail.com: Ordinal number type inequality after
deserialization
http://code.google.com/p/json-simple/issues/detail?id=64
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);
}
Comment #1 on issue 64 by fangyid...@gmail.com: Ordinal number type
inequality after deserialization
http://code.google.com/p/json-simple/issues/detail?id=64
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.
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.
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.
Comment #4 on issue 64 by fangyid...@gmail.com: Ordinal number type
inequality after deserialization
http://code.google.com/p/json-simple/issues/detail?id=64
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.
That would definitely help. Thanks!