1

I'm dealing with the strange javax.json library. So here's the problem:

I need to cast an Object of type JsonValue to either JsonObject or JsonArray so I can call the methods getJsonObject and getJsonArray of it. Both JsonArray and JsonObject have the same method names with the same functionalities but they're not implemented methods, they are methods defined on each of them! See: JsonObject, JsonArray.

The obvious solution would be to verify the type and then cast depending on the verified type, like this:

            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);
            }

but it'd require too many repetitions on my code. So I ask:

1) If both JsonObject and JsonArray have the same methods, why they're not implementations of some interface?

2) Is there a more elegant way to cast the object to JsonObject or JsonArray at the same time by using some trick? Do you know any way to make this situation better?

Jon Heller
  • 34,999
  • 6
  • 74
  • 132
PPP
  • 1,279
  • 1
  • 28
  • 71

2 Answers2

2

Although the 2 methods on the 2 different objects have the same name, their signatures are in fact different. JsonObject#getJsonObject(String) accepts a String key identifying the value to pull from a JSON object of key-value pairs. JsonArray#getJsonObject(int) accepts an int index identifying which element to pull the value from in a JSON array.

In this case, there is no appropriate common interface that the 2 classes can share. Your code will have to know whether to inspect a JSON object or a JSON array and cast accordingly.

Since the 2 methods in question do not have the same signature, there are not other alternatives for calling them in a "common way". You could potentially use reflection, but this risks making the code more confusing. For example, Apache Commons includes MethodUtils#invokeMethod. You could potentially use that to invoke any method named "getJsonObject", accepting any kind of object (either String or int). Although using this would make it "common code" across both cases, it's potentially confusing for people reading the code later. They'd have to keep track of the fact that this is using reflection, and that the passed argument might be either String or int, and that it really all works out thanks to it being either a JSON object or array. Instead, I would favor just doing the downcast in this case.

Chris Nauroth
  • 9,614
  • 1
  • 35
  • 39
1

Chris is right, Your code will have to know whether to inspect a JSON object or a JSON array and cast accordingly. However, if you are ok with adding an external library, I would recommend gson for parsing Json This library has JsonElement class which should fit good in your case. look at this to see how it works

Sahil Manchanda
  • 9,812
  • 4
  • 39
  • 89