Есть ли способ обработать неконтролируемое предупреждение о сотворении без использования Supress в Kotlin? - PullRequest
0 голосов
/ 30 апреля 2020

Я использую ViewModelFactory в своем приложении android для передачи некоторых данных в мою ViewModel из фрагмента. Я получаю необязательное предупреждение. Если я использую Supress, предупреждение исчезнет. Мне было интересно, есть ли способ справиться с этим без использования 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 предупреждение.

1 Ответ

0 голосов
/ 30 апреля 2020

Нет, неконтролируемое приведение означает, что компилятор не может гарантировать, что приведение завершится неудачно или успешно.

В большинстве случаев вы ничего не можете добавить, чтобы изменить это, потому что компилятору просто не хватает информации. Обычно это происходит вокруг generis, поскольку T может представлять много разных типов.
Вы должны добавить правильные проверки типов перед приведением, чтобы вы были уверены, что приведение выполнено успешно.

Вы можете подавить предупреждение. Делая это, вы, как разработчик, обещаете компилятору, что вы уверены, что приведение будет всегда успешным.


Код, как он есть, не может дать такое обещание. Если функция create вызывается с чем-либо, кроме BookReaderViewModel, она обработает sh из-за того, что приведение не выполнено.

Вот пример, в котором безопасно подавить предупреждение, поскольку оно проверяет до того, как произойдет приведение :

    @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}")
    }
...