在Result类型的Flowable上调用map函数会引发ClassCastException

时间:2019-07-01 02:05:52

标签: generics kotlin rx-java2

我正在尝试将Result类型的Flowable中的值映射到其他Result类型。在地图块中,我只是在Result上调用mapCatching。而不是返回映射的值,而是引发ClassCastException。我写了一个简单的测试来说明我遇到的问题。

@Test
    fun test() {
        Flowable.just(Result.success(1))
                .map { result ->
                    result.mapCatching { input -> input.toString() }
                }
                .test()
                .values()
                .forEach {
                    println(it)
                }
    }

这将返回以下异常:

java.lang.ClassCastException: kotlin.Result$Failure cannot be cast to kotlin.Result

编辑: 用我自己的映射代码替换mapCatching方法会导致Flowable以其他ClassCastException终止:

@Test
    fun test() {
        Flowable.just(Result.success(1))
                .map { result ->
                    if (result.isFailure) {
                        return@map Result.failure<String>(result.exceptionOrNull()!!)
                    } else {
                        return@map Result.success(result.getOrNull()!!.toString())
                    }
                }
                .test()
                .errors()
                .forEach {
                    println(it)
                }
    }

此测试将打印以下内容:

java.lang.ClassCastException: kotlin.Result cannot be cast to java.lang.Number

1 个答案:

答案 0 :(得分:0)

Result类是一个内联类,编译器会在内部尝试尽可能地将其转换为包装的类型。从Kotlin代码调用时,此方法工作正常,但RxJava是用Java编写的。有关更多信息,请参见this article

在这种情况下,我设法通过在源代码中解开Result类并仅使用封装的类型来解决该问题。错误被传播,并最终在订户处包装在结果类中。

类似这样的东西:

List<BinaryPart> saveAll(List<BinaryPart> binaryParts);