Search code examples
jsonkotlinjson-simple

Casting JSONArray to Iterable<JSONObject> - Kotlin


I am using Json-Simple in Kotlin.

In what situations could this cast:

val jsonObjectIterable = jsonArray as Iterable<JSONObject>

Become dangerous? jsonArray is a JSONArray object.


Solution

  • You can cast it successfully, since JSONArray is-A Iterable. but it can't make sure each element in JSONArray is a JSONObject.

    The JSONArray is a raw type List, which means it can adding anything, for example:

    val jsonArray = JSONArray()
    jsonArray.add("string")
    jsonArray.add(JSONArray())
    

    When the code operates on a downcasted generic type Iterable<JSONObject> from a raw type JSONArray, it maybe be thrown a ClassCastException, for example:

    val jsonObjectIterable = jsonArray as Iterable<JSONObject>
    
    //    v--- throw ClassCastException, when try to cast a `String` to a `JSONObject`
    val first = jsonObjectIterable.iterator().next()
    

    So this is why become dangerous. On the other hand, If you only want to add JSONObjecs into the JSONArray, you can cast a raw type JSONArray to a generic type MutableList<JSONObject>, for example:

    @Suppress("UNCHECKED_CAST")
    val jsonArray = JSONArray() as MutableList<JSONObject>
    
    //      v--- the jsonArray only can add a JSONObject now
    jsonArray.add(JSONObject(mapOf("foo" to "bar")))
    
    //      v--- there is no need down-casting here, since it is a Iterable<JSONObject>
    val jsonObjectIterable:Iterable<JSONObject> = jsonArray 
    
    val first = jsonObjectIterable.iterator().next()
    
    println(first["foo"])
    //           ^--- return "bar"