3 回答

TA貢獻1951條經驗 獲得超3個贊
選項 0:長 If 語句
我認為這太復雜了,尤其是當鏈條變得更長時。我會考慮使用遠程類似解決方案的唯一情況是,如果用戶需要確切地知道問題出在哪里,并且有關于如何解決這個問題以及在非常特定的用例中如何發生這種情況的具體指南,但是在這種情況下如果您需要大量的 if 語句和 log 語句。
選項 1:嘗試捕獲
正如您所建議的那樣,Try-catch 確實是可能的,但是您需要確保捕獲當 JSON 字段不存在或類型錯誤時可能發生的所有可能的異常,例如 ClassCastException 和 NullPointerException。它很短但不是很優雅,正如其他回答者所說可能隱藏其他異常(但您仍然可以記錄堆棧跟蹤)。
選項 2:Java 8 可選
另一種選擇是找到一個允許您使用 Java 8 可選類型的庫。例如,建議使用Jackson。這更優雅,但也可以成為一個大型連鎖店。這也為您的項目增加了一種依賴。
選項 3:路徑表達式
第三種選擇是使用路徑表達式JsonPath,您可以將所有語句放入一個表達式中并獲取該表達式的所有結果。在我看來,這是完美的用例,也是迄今為止最好的解決方案。唯一的缺點是這會給您的項目增加一個依賴項。

TA貢獻1820條經驗 獲得超10個贊
請建議在這種情況下是否有任何有效的理由來放置很長的 if 條件,而不是僅僅嘗試 - 捕獲 - 記錄并繼續。
以下是幾個原因:
效率:創建、拋出和捕獲異常的成本相對較高。到底有多昂貴取決于版本,也可能取決于上下文。在最近的版本中,JIT 編譯器可以(據我所知)將某些序列優化為條件分支。但是,如果您要記錄異常,那么 JVM 將必須創建一個異常對象并填充堆棧跟蹤,這是最昂貴的部分。
如果您登錄
NullPointerException
:json.getJSONObject("c").getJSONArray("f").getJSONObject(1).getString("b")
您可能無法判斷哪個組件丟失或為空。堆棧跟蹤中的行號不足以區分情況。(
JSONException
異常消息將為您提供更多線索。)您也無法區分
json
is 的情況null
,這可能是另一種問題;即一個錯誤。如果您將其視為數據錯誤,則很難找到并修復代碼錯誤。如果您捕獲所有異常(如另一個答案所建議的),則可能會隱藏更多類別的錯誤。餿主意。
您還可以分享一下使用 JSONException 在這種情況下有什么“優點”嗎?
唯一真正的“優點”是它可能會減少代碼,特別是如果您可以將try ... catch放在很多這樣的代碼中。
最重要的是,您需要自己權衡這一點。其中一個因素是您獲得的 JSON 與代碼預期不符的可能性有多大。這部分取決于生成 JSON 的內容。

TA貢獻1827條經驗 獲得超8個贊
感謝上面的回復,下面是問題的解決方法。
JSONPath對于我提到的場景效果最好。
首先創建一個com.jayway.jsonpath.Configuration類型的配置對象
Configuration?conf?=?Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).mappingProvider(new?JsonOrgMappingProvider()).jsonProvider(new?JsonOrgJsonProvider()).build();
Option.SUPPRESS_EXCEPTIONS?- 這將有助于在元素丟失時抑制異常
mappingProvider(new JsonOrgMappingProvider()).jsonProvider(new JsonOrgJsonProvider()?- 這使用正確的提供程序,這樣當我們解析 json 時,我們不需要將 JSONObject 轉換為 String,從而提供最佳性能。
DocumentContext?docContext?=?JsonPath.using(conf).parse(json);
如果我們使用默認提供程序,那么我們需要如下解析 JSONObject
DocumentContext?docContext?=?JsonPath.using(conf).parse(json.toString());
然后讀取我使用的元素
docContext.read("$.a.b.c.d.values[0].e.f")
現在性能也達到最佳狀態?;ㄙM更多時間和內存的原因是
我在循環中同時閱讀和解析。后來我將解析移出了循環。
我正在使用默認提供程序并正在執行 json.toString()
添加回答
舉報