4

我在我的 android 应用程序中使用 ViewModelFactory 将一些数据从 Fragment 传递给我的 ViewModel。我收到未经检查的演员表警告。如果我使用抑制,警告就会消失。我想知道有没有办法在不使用 Supress("UNCHECKED_CAST") 的情况下处理这个问题

我用来创建 ViewModelFactory 的代码

val factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
        //factory to pass necessary data to ViewModel
        @NonNull
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            return activity?.application?.let {
                BookReaderViewModel(
                    it,
                    "local",//todo:remote or local book. value will come from arguments
                    1//todo: bookId will come from arguments
                )
            } as T
        }
    }

因为 T 收到警告。

4

1 回答 1

0

不,未经检查的强制转换意味着编译器不能保证强制转换会失败或成功。

在大多数情况下,您无法添加任何内容来更改它,因为编译器根本没有足够的信息。这通常发生在类属周围,因为 T 可以代表许多不同的类型。
必须在转换之前添加正确的类型检查,以确保转换成功。

您可以抑制警告。通过这样做,作为开发人员,您向编译器保证您确信转换将始终成功。


代码本身不能做出这样的承诺。如果create使用除 a 之外的任何其他内容调用该函数BookReaderViewModel,它将崩溃,因为强制转换不成功。

这是一个可以安全地抑制警告的示例,因为它会在强制转换之前进行检查:

    @NonNull
    @Supress("UNCHECKED_CAST")
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        val application = activity?.application ?: return null
        if (modelClass == BookReaderViewModel::class.java) {
            return BookReaderViewModel(
                application,
                "local",
                1) as T
        }
        // return null or throw exception here
        throw IllegalArguentException("Factory cannot make ViewModel of type ${modelClass.simpleName}")
    }
于 2020-04-30T09:46:45.877 回答