Cannot cast to an Extended Class in Java
Asked Answered
F

2

14

I looked around for a similar issue but couldn't find anything that matched it.

I'm trying to extend the built-in JSONObject to add some functionality, like so:

public class MyJSONObject extends JSONObject {

    // Easily return an integer from a JSONObject, handling when the value is null.
    //
    public Integer getIntegerUnlessNull(String key) throws JSONException {
        String key_value = this.getString (key);

        if ( key_value.equals("null") ) {
            return null;

        } else {
            return Integer.parseInt( key_value );
        }
    }
}

However, when I try to cast it, I get a java.lang.ClassCastException error:

private JSONArray    jsonClients;
        MyJSONObject clientJSONRecord;

clientJSONRecord = (MyJSONObject) jsonClients.getJSONObject(0);

The full error message is:

java.lang.ClassCastException: org.json.JSONObject cannot be cast to com.insightemissions.trak.extensions.MyJSONObject

Any help?

Cheers,

JP

Fiske answered 6/12, 2013 at 4:38 Comment(6)
Please post your json which you trying to parse....Pacifistic
If the source is not real instance of MyJSONObject, it is not possible to cast.Artificer
The JSONObject comes from this library: json.org/javadoc/org/json/JSONObject.html#JSONObject()Fiske
@HarshitRathi I don't think the actual JSON matters in this case. If I simply remove the casting, the code works fine. I'm simply trying to add some additional functionality to keep the code DRY.Fiske
@Nambari Can you explain a bit more. The getJSONObject(index) methods results in a JSONObject instance.Fiske
docs.oracle.com/javase/tutorial/java/IandI/subclasses.html may help you.Artificer
R
18

jsonClients.getJSONObject(0) returns an object of the type JSONObject which is your parent type.

You cannot cast it to the inherited type. It only works the other way, i.e. casting an inherited class to a parent class. This has nothing to do with your objects in particular, it just the way inheritance works.

Because you get an instance of JSONObject from the method and you cannot control how it's instantiated, you could add a constructor to your MyJSONObject class to create an object from the parent object:

public MyJSONObject(JSONObject parent) {
    super(parent.toString());
}

And use it this way:

JSONObject parent = jsonClients.getJSONObject(0);
MyJSONObject child = new MyJSONObject(parent);
Readily answered 6/12, 2013 at 4:47 Comment(7)
You're correct, that's what it returns. How do I go about turning it into a MyJSONObject to unlock the additional functionality?Fiske
Hmm... okay, making more sense, except why the parent.toString()?Fiske
I think that's a JSONObject constructor that will be easiest to use.Readily
That constructor doesn't exist. How would I go about constructing a JSONObject from an existing JSONObject?Fiske
It is in the documentation though... I used the link you provided.Readily
Sorry, you're right. Worked like a charm. just had to fix a missing colon in your reply. Nice work Szymon, thanks.Fiske
let us continue this discussion in chatFiske
V
2

The problem you have is that the objects inside the JSONArray (I presume the JSONArray object is created by the library) do not contain MyJSONObject objects that are defined by you.

Your code would work only if you created the JSONArray yourself and populated it with MyJSONObject objects.

Given what you are trying to achieve with this "extended functionality", I think inheritance is much of an overkill.

Why not just use a helper method?

public Integer getIntegerUnlessNull(JSONObject, String key) throws JSONException {
    String key_value = object.getString (key);

    if ( key_value.equals("null") ) {
        return null;

    } else {
        return Integer.parseInt( key_value );
    }
}

Then you can just do this:

Integer getInteger = getIntegerUnlessNull(object, "key");
if (getInteger == null) {
    // if null do something
}
Vicarious answered 6/12, 2013 at 5:1 Comment(3)
In this particular case, you're probably right with going with the helper class, however, I'm keen to find out how to extend it with more functionality in case I need to build on it more.Fiske
I am afraid if you really wish to go in that direction, you have to ensure that the library builds its JSON objects using your custom class. In other words, you will have to acquire the library's source code and rewrite it yourself.Vicarious
Really, that's the only way, you think?Fiske

© 2022 - 2024 — McMap. All rights reserved.