2017-07-20 88 views
1

我正在處理奇怪的javax.json庫。因此,這裏的問題:javax.json對象具有相同的方法,但它們不是通用接口的實現。如何投射?

我需要投JsonValue類型的Object要麼JsonObjectJsonArray這樣我就可以調用的方法getJsonObject和它getJsonArrayJsonArrayJsonObject都具有相同的功能相同的方法名稱,但它們不是實現的方法,它們是在它們中的每一個上定義的方法!參見:JsonObject,JsonArray

明顯的解決辦法是驗證類型,然後根據驗證的類型轉換,就像這樣:

  if (current.getValueType().equals(JsonValue.ValueType.OBJECT)) { 
       current = ((JsonObject) current).getJsonObject(node); 
      } else if (current.getValueType().equals(JsonValue.ValueType.ARRAY)) { 
       current = ((JsonArray) current).getJsonObject(node); 
      } 

,但它會要求我的代碼太多的重複。所以我問:

1)如果JsonObjectJsonArray都有相同的方法,爲什麼他們不是一些接口的實現?

2)是否有一種更優雅的方式,通過使用一些技巧來同時將對象投射到JsonObjectJsonArray?你知道有什麼方法可以改善這種狀況嗎?

回答

2

儘管2個不同對象上的2個方法具有相同的名稱,但它們的簽名實際上是不同的。 JsonObject#getJsonObject(String)接受一個String鍵,標識從鍵 - 值對的JSON對象中拉取的值。 JsonArray#getJsonObject(int)接受一個int索引,該索引標識哪個元素將從JSON數組中提取值。

在這種情況下,沒有合適的2個類可以共享的通用接口。您的代碼必須知道是否檢查JSON對象或JSON數組並進行相應的轉換。

由於所討論的兩種方法沒有相同的簽名,因此沒有其他方法以「常用方式」調用它們。您可能會使用反射,但這會使代碼更容易混淆。例如,Apache Commons包含MethodUtils#invokeMethod。您可以使用它來調用任何名爲「getJsonObject」的方法,接受任何類型的對象(Stringint)。雖然使用這種方式會使它在兩種情況下都成爲「通用代碼」,但這可能會讓人們在稍後閱讀代碼時感到困惑。他們必須記錄這是使用反射的事實,並且傳遞的參數可能是Stringint,並且它實際上都是有效的,這要歸功於它是JSON對象還是數組。相反,在這種情況下,我會傾向於做低調。

1

Chris是正確的,您的代碼將必須知道是否檢查JSON對象或JSON數組並進行相應的轉換。但是,如果您可以添加外部庫,我會建議gson解析Json 此庫有JsonElement類,它應該適合您的情況。看看this,看看它是如何工作的

相關問題