JSONObject.toString(int) 怎么会抛出 JSONException?
How can JSONObject.toString(int) throw JSONException?
我在 JSONObject.toString(int) 文档中注意到了这一点
Throws: JSONException - If the object contains an invalid number.
如果事先进行了 NaN/Infinity 检查(在解析时和 .put("blah", Double.NAN)
之类的语句中,对象怎么可能包含无效数字?
哪些语句会抛出该异常?
我还在文档中读到 .toString() 没有 args 不会抛出任何东西,所以我认为异常可能与作为参数传递的整数有关;但即使是零、负数或整数。MAX/MIN_VALUE 它仍然有效。
那么什么时候应该期望 .toString(int) 抛出异常,应该如何处理呢?
toString()
方法不会抛出异常,因为它必须覆盖 java.lang.Object
的 public void toString()
方法的签名。在 org.json.JSONObject
中,通用 toString()
方法实际上失败了,因为源代码是:
/**
* Make a JSON text of this JSONObject. For compactness, no whitespace is
* added. If this would not result in a syntactically correct JSON text,
* then null will be returned instead.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @return a printable, displayable, portable, transmittable representation
* of the object, beginning with <code>{</code> <small>(left
* brace)</small> and ending with <code>}</code> <small>(right
* brace)</small>.
*/
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
这个方法依赖于toString(int)
方法,如果它抛出异常,它会捕获它并且returns null。
根据toString(int)
的描述,当org.json.JSONObject
的其中一个元素中有一个无效数字时抛出异常;但是查看代码可能会因为其他原因抛出此异常。
当您使用 toString(int)
堆栈跟踪最终调用 write()
方法来解析对象本身时,对于从 json 对象到字符串的某些转换可能会抛出异常:
static final Writer writeValue(Writer writer, Object value,
int indentFactor, int indent) throws JSONException, IOException {
if (value == null || value.equals(null)) {
writer.write("null");
} else if (value instanceof JSONObject) {
((JSONObject) value).write(writer, indentFactor, indent);
} else if (value instanceof JSONArray) {
((JSONArray) value).write(writer, indentFactor, indent);
} else if (value instanceof Map) {
new JSONObject((Map<String, Object>) value).write(writer, indentFactor, indent);
} else if (value instanceof Collection) {
new JSONArray((Collection<Object>) value).write(writer, indentFactor,
indent);
} else if (value.getClass().isArray()) {
new JSONArray(value).write(writer, indentFactor, indent);
} else if (value instanceof Number) {
writer.write(numberToString((Number) value));
} else if (value instanceof Boolean) {
writer.write(value.toString());
} else if (value instanceof JSONString) {
Object o;
try {
o = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
writer.write(o != null ? o.toString() : quote(value.toString()));
} else {
quote(value.toString(), writer);
}
return writer;
}
但是,如果正如您在问题中所说(和@Carlos Rodriguez 评论),所有检查都是在创建对象时执行的,可能 toString(int)
方法从未抛出异常。
希望对您有所帮助,
查看 JSONObject.toString(int)
和 JSONObject.toString()
的实现会有所帮助:
public String toString(int indentFactor) throws JSONException {
StringWriter w = new StringWriter();
synchronized (w.getBuffer()) {
return this.write(w, indentFactor, 0).toString();
}
}
write
方法写入 Writer
并将任何 IOException 作为 JSONException 重新抛出。如果您的分析是正确的,那么这样的 IOException 将永远不会发生,因为 StringWriters 也不会抛出 IOException。因此,让此方法抛出 JSONException 似乎只是一个实现决定,文档具有误导性。
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
toString()
实现证实了这个分析:这里 API 设计者决定捕获任何异常,这只有在 从未 抛出异常时才有意义.
最好将 try-catch
移动到 toString(int)
中,以便将这两个方法从其签名中的 throw 子句中释放出来。
我刚刚 运行 遇到这个问题。
这是一个示例,它会导致 JSONObject.toString(int)
方法抛出 JSONException
:
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("num", Double.NaN);
JSONObject obj = new JSONObject();
obj.put("map", map);
obj.toString(0);
}
在我看来应该由 JSONObject.put()
方法抛出异常,但显然这里没有进行检查...
我在 JSONObject.toString(int) 文档中注意到了这一点
Throws: JSONException - If the object contains an invalid number.
如果事先进行了 NaN/Infinity 检查(在解析时和 .put("blah", Double.NAN)
之类的语句中,对象怎么可能包含无效数字?
哪些语句会抛出该异常?
我还在文档中读到 .toString() 没有 args 不会抛出任何东西,所以我认为异常可能与作为参数传递的整数有关;但即使是零、负数或整数。MAX/MIN_VALUE 它仍然有效。
那么什么时候应该期望 .toString(int) 抛出异常,应该如何处理呢?
toString()
方法不会抛出异常,因为它必须覆盖 java.lang.Object
的 public void toString()
方法的签名。在 org.json.JSONObject
中,通用 toString()
方法实际上失败了,因为源代码是:
/**
* Make a JSON text of this JSONObject. For compactness, no whitespace is
* added. If this would not result in a syntactically correct JSON text,
* then null will be returned instead.
* <p>
* Warning: This method assumes that the data structure is acyclical.
*
* @return a printable, displayable, portable, transmittable representation
* of the object, beginning with <code>{</code> <small>(left
* brace)</small> and ending with <code>}</code> <small>(right
* brace)</small>.
*/
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
这个方法依赖于toString(int)
方法,如果它抛出异常,它会捕获它并且returns null。
根据toString(int)
的描述,当org.json.JSONObject
的其中一个元素中有一个无效数字时抛出异常;但是查看代码可能会因为其他原因抛出此异常。
当您使用 toString(int)
堆栈跟踪最终调用 write()
方法来解析对象本身时,对于从 json 对象到字符串的某些转换可能会抛出异常:
static final Writer writeValue(Writer writer, Object value,
int indentFactor, int indent) throws JSONException, IOException {
if (value == null || value.equals(null)) {
writer.write("null");
} else if (value instanceof JSONObject) {
((JSONObject) value).write(writer, indentFactor, indent);
} else if (value instanceof JSONArray) {
((JSONArray) value).write(writer, indentFactor, indent);
} else if (value instanceof Map) {
new JSONObject((Map<String, Object>) value).write(writer, indentFactor, indent);
} else if (value instanceof Collection) {
new JSONArray((Collection<Object>) value).write(writer, indentFactor,
indent);
} else if (value.getClass().isArray()) {
new JSONArray(value).write(writer, indentFactor, indent);
} else if (value instanceof Number) {
writer.write(numberToString((Number) value));
} else if (value instanceof Boolean) {
writer.write(value.toString());
} else if (value instanceof JSONString) {
Object o;
try {
o = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
writer.write(o != null ? o.toString() : quote(value.toString()));
} else {
quote(value.toString(), writer);
}
return writer;
}
但是,如果正如您在问题中所说(和@Carlos Rodriguez 评论),所有检查都是在创建对象时执行的,可能 toString(int)
方法从未抛出异常。
希望对您有所帮助,
查看 JSONObject.toString(int)
和 JSONObject.toString()
的实现会有所帮助:
public String toString(int indentFactor) throws JSONException {
StringWriter w = new StringWriter();
synchronized (w.getBuffer()) {
return this.write(w, indentFactor, 0).toString();
}
}
write
方法写入 Writer
并将任何 IOException 作为 JSONException 重新抛出。如果您的分析是正确的,那么这样的 IOException 将永远不会发生,因为 StringWriters 也不会抛出 IOException。因此,让此方法抛出 JSONException 似乎只是一个实现决定,文档具有误导性。
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
toString()
实现证实了这个分析:这里 API 设计者决定捕获任何异常,这只有在 从未 抛出异常时才有意义.
最好将 try-catch
移动到 toString(int)
中,以便将这两个方法从其签名中的 throw 子句中释放出来。
我刚刚 运行 遇到这个问题。
这是一个示例,它会导致 JSONObject.toString(int)
方法抛出 JSONException
:
public static void main(String[] args) {
Map<String, Double> map = new HashMap<>();
map.put("num", Double.NaN);
JSONObject obj = new JSONObject();
obj.put("map", map);
obj.toString(0);
}
在我看来应该由 JSONObject.put()
方法抛出异常,但显然这里没有进行检查...