java - 如何避免 JSONObject Null 检查
问题描述
我有如下 JSON
{
"a1": "aaa",
"b1": 333,
"c1": {
"c1": "ccc",
"d1": "ddd",
"f1": [
{"a1": "xyz"},
{"b1": "lmn"},
{"c1":123.00}
]
}
}
我正在将文件读入 String 并创建一个 JSONObject 如下
JSONObject json = new JSONObject(new JSONTokener(str));
JSON 是从外部进入我的应用程序的,因此内容有时会非常不同。假设它可以完全为空,或者某些元素可以为空,或者数组大小可以为 0 或 1 或更多等。
当我处理 JSONObject 时,我可以继续使用检查所有元素
json.has and !=null
这样它就不会抛出任何异常。
我可以有如下代码
if(
json.has("c")
&& json.getJSONObject("c")!= null
&& json.getJSONObject("c").has("f")
&& json.getJSONObject("c").getJSONArray("f").length() > 1
&&json.getJSONObject("c").getJSONArray("f").getJSONObject(1).has("b")
){
String x = json.getJSONObject("c").getJSONArray("f").getJSONObject(1).getString("b");
}
这使得代码具有一长串 if 条件。
但是我在想,我可以用 try catch 来附上语句
try {
String x = json.getJSONObject("c").getJSONArray("f").getJSONObject(1).getString("b");
}catch(JSONException e) {
//log and proceed
}
请建议在这种情况下是否有任何正当理由放置一个较长的 if 条件,而不是仅仅尝试 - 捕获 - 记录并继续。
如果在这种情况下使用 JSONException 有任何“优点”,你也可以分享吗?
解决方案
选项 0:长 If 语句
我认为这太令人费解了,尤其是当链条变长时。我会考虑远程类似解决方案的唯一情况是,如果用户需要确切地知道问题出在哪一点,并且有关于如何解决这个问题以及在非常具体的用例中如何发生这种情况的具体指导方针,但是在那个如果你需要大量的 if 语句和 log 语句。
选项 1:Try-Catch
正如您所建议的,try-catch 确实是可能的,但是您需要确保捕获当 JSON 字段不存在或类型错误时可能发生的所有可能异常,例如 ClassCastException 和 NullPointerException。它很短但不是很优雅,正如其他回答者所说可能隐藏其他异常(但您仍然可以记录堆栈跟踪)。
选项 2:Java 8 可选
另一种选择是找到一个允许您使用 Java 8 Optional 类型的库。例如,建议使用Jackson。这更优雅,但也可以成为一个大链。这也为您的项目增加了一个依赖项。
选项 3:路径表达式
第三种选择是使用路径表达式JsonPath,您可以将所有语句放入一个表达式中并获得所有结果。在我看来,这是一个完美的用例,也是迄今为止最好的解决方案。唯一的缺点是这为您的项目增加了一个依赖项。
推荐阅读
- google-kubernetes-engine - 在哪里可以找到 ILB 上的节点端口信息,该信息将流量发送到使用节点端口公开的 GKE 服务
- sql - 检查一周的日期是否位于两个特定日期之间 SQL ORACLE
- sql - 如何将 SQL Server 函数的返回值分配给变量
- c++ - 如何创建格式规则以在打开大括号之前没有空格?
- django - 我可以在 VueJS 中检索请求的标头或其内容吗?
- c# - 如何使用来自 UWP 项目的 4 个参数启动 win32 可执行桌面
- flutter - 如何在颤动中显示进度指示器?
- python - 如何使用列表理解从函数中的函数中提取键值?
- c++ - 如何将值输入到已定义的数组中?
- java - 如何在一行中输入多个不同类型的变量?例如 -> 字符串字符串 int 字符串 int