Unexpected cast error: java.lang.Object[] cannot be cast to uk.innerfuse.androidapplication.TreeNode[]

(wdb) #1

IDE: Fire
Version: Version 10.0.0.2400 (develop) built on talax, 20190503-102703. Commit dc2f219.
Target (If relevant): Android
Description:
I am getting a runtime error in Android when using java.lang.Object[] cannot be cast to uk.innerfuse.androidapplication.TreeNode[] when using my (beloved) Result-enum. I am not sure why I am getting this error as I am not using Object[] as far as I know.

The code appears to fail at:

    public static func fetchItems(completion: (Result<LocationNodeList>) -> ()) {
        completion(.success([]))
    }

when I am trying to get the actual value out of my Result-enum using the dematerialize-method which does the following when using the following Result definition: Result<LocationNodeList>

    public func dematerialize() throws -> Value {
        switch self {
            case let .success(value):
                return value
            case let .failure(error):
                throw error
        }
    }

I have also tried the alternative were I am returning let items = LocationNodeList() instead of just [] but then I am getting the same error. When using the items I am using the line: completion(.success(items))

Expected Behavior:
I would be able to execute the code included in the reproducible project without runtime errors

Actual Behavior:
I am getting a runtime cast error when running my code.

Steps:
Please find a reproducible project attached

BugReport5.zip (255.6 KB)

(marc hoffman) #2

not sure if native java arrays should be castable between types (I known on .NET they aren’t), because they aren’t co/contravariant…

(wdb) #3

What do you mean it should not be castable between types? I don’t think I am switching between types? The type the Result-enum is storing is Result<LocationNodeList> and my function is returning it (e.g. via let items = LocationNodeList()) but somehow Java decides I have returned java.lang.Object[]

(marc hoffman) #4

java.lang.Object[] and uk.innerfuse.androidapplication.TreeNode[]

are two distinct types without ancestry. while any type X might descend from java.langObject, the array of X type does not descend from array of object (if it did, you could cast X[] to object[], add a Y to it, and you’d be sad, because you broke type safety).

The error message states you have a reference that holds an java.lang.object[]. so you cannot just cast that to a. more strongly-typed array.

(wdb) #5

Originally, I thought the problem as the line: completion(.success([])) and its use of [] but even when I initialise the expect type like:

let result = LocationNodeList()`
completion(.success(result))

I really don’t know where I would be using java.lang.object[]. My LocationNodeList is a typealias for a [TreeNode<Location>]. Yeah TreeNode is a class which stores the struct Location.

(RemObjects) #6

Thanks, logged as bugs://82532

(RemObjects) #7

bugs://82532 got closed with status fixed.

1 Like