Почему плохое литье вызывает исключение ActivityNotFound Exception в Android с использованием Kotlin?

Недавно я столкнулся с исключением при написании программы, и мне потребовалось много времени на отладку просто потому, что компилятор выдал мне неправильное исключение.

Вот мой код активности:

 private var mCheatMap = HashMap<Int, Boolean>()

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_quiz)

    mCheatMap = savedInstanceState?.getSerializable(KEY_CHEATER) as HashMap<Int, Boolean> ?: HashMap<Int, Boolean>()
}

Во время выполнения мое приложение разбилось, и когда я заглянул в журналы, в нем было сказано ActivityNotFound исключение, а в предложении было сказано, что, возможно, я не объявил активность в моем AndroidManifest.xml

С моей стороны все казалось безошибочным, как вдруг я случайно сделал приведение своей переменной mCheapMap к безопасному приведению, и все стало работать отлично. например.:

 private var mCheatMap = HashMap<Int, Boolean>()

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_quiz)

    mCheatMap = savedInstanceState?.getSerializable(KEY_CHEATER) as? HashMap<Int, Boolean> ?: HashMap<Int, Boolean>()
}

Теперь у меня есть некоторые неясности:

  1. Почему компилятор выдал мне исключение ActivityNotFound, когда у меня была проблема с кастингом?

  2. Почему использование оператора безопасного приведения решило проблему, потому что даже без оператора безопасного приведения мое приведение было правильным?


person HQuser    schedule 14.03.2018    source источник
comment
@user2340612 user2340612 вот в чем проблема, исключение, которое я получаю, это исключение ActivityNotFound, которое действительно не имеет смысла. P.S. спасибо, что сняли мой второй вопрос.   -  person HQuser    schedule 14.03.2018
comment
Возможно, ActivityNotFound можно объяснить тем фактом, что ClassCastException выбрасывается в Activity onCreate, поэтому создание не удается, и Activity не может быть найдено средой выполнения. Но это только мое предположение, могу ошибаться   -  person user2340612    schedule 14.03.2018
comment
Это больше похоже на исключение нулевого указателя, чем на исключение приведения класса... Я могу ошибаться.   -  person Ishita Sinha    schedule 14.03.2018
comment
ОП сказал, что использование безопасного приведения решило проблему, чего не должно быть в случае с NPE. Кроме того, с оператором безопасного вызова (?.) и оператором elvis значения null обрабатываются безопасно (если только NPE не произойдет где-то еще).   -  person user2340612    schedule 14.03.2018


Ответы (1)


Во время выполнения вы должны получить ClassCastException, если проблема связана с неправильным приведением (кстати, это не компилятор выдает исключение, а среда выполнения. Однако компилятор/LINT должен предупредить вас о «непроверенном приведении»).

Относительно вашего второго вопроса, безопасное приведение вернет null в случае неудачного приведения, из-за чего вы попадете в ветку "else" оператора elvis (?:), поэтому вы создадите новый пустой HashMap<Int, Boolean> и назначите его своему mCheatMap переменная. Этого не происходит в вашем первом примере, так как сбой приведения генерирует исключение вместо того, чтобы просто возвращать null, поэтому ветвь "else" оператора elvis никогда не может быть выполнена (для этого вы должны получить еще одно предупреждение от компилятора/LINT) .

person user2340612    schedule 14.03.2018