JSON-java
JSON-java copied to clipboard
Creating JSONObject from Map vs String misses null values
If we create a JSONObject
from a string containing null
values, those are parsed internally as JSONObject.NULL
[see 1]. However, when creating a JSONObject
from a Map
, null
values are ignored [see 2].
This is a problem since we have an inconsistency. Either both cases ignore nulls (this wouldn't represent reality), or both convert Java nulls to JSONObject.NULL
.
1: https://github.com/stleary/JSON-java/blob/7d6b76de375f8fbde93226ed77dbf51e4c70e29a/src/main/java/org/json/JSONObject.java#L2309-L2311 2: (there's no ELSE) https://github.com/stleary/JSON-java/blob/7d6b76de375f8fbde93226ed77dbf51e4c70e29a/src/main/java/org/json/JSONObject.java#L307-L309
This is as-designed.
When parsing a String
, we are parsing actual JSON where null
is a value.
When transforming a Map
, in Java, null
means "no value" which is similar to undefined
in JavaScript. The author of this library made the conscious choice to treat Java null
like JavaScript undefined
.
Whether or not that was the best choice is a little late for this project as it would be a breaking change for people that have been using this project for 20 or so years.
Whether or not that was the best choice is a little late for this project as it would be a breaking change for people that have been using this project for 20 or so years.
Thi is completely understandable. However, I still believe it could be solved, maybe by using a second parameter indicating to threat nulls as Json nulls... (just an idea).
Regarding...
When transforming a
Map
, in Java,null
means "no value"
...this is not exactly true: since there's still a key in the Map
for that value, and all methods regarding Map
s threat that as an explicit <key, null>
entry.
Java is a strongly typed language and null
does not have a type. A variable assigned null
has no value as it's un-typed.
JavaScript is an un-typed/loosely-typed language, so null
is an actual value.
This design does not seem internally consistent.
I think it would be reasonable to expect JSONObject.toMap
to be the inverse of new JSONObject(Map)
.
new JSONObject("{k:null}")
includes the null-valued entry
new JSONObject("{k:null}").toMap()
includes the null-valued entry
new JSONObject(new JSONObject("{k:null}").toMap())
drops the null-valued entry
Closing this issue since no fix was proposed. The inconsistency is noted, but changing current behavior might break existing applications. If anyone disagrees, please post here.