0

我最近在编写程序时遇到了一个异常,仅仅因为编译器给了我一个错误的异常,我花了很多时间来调试。

这是我的活动代码:

 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. 为什么使用安全转换运算符解决了问题,因为即使没有安全转换运算符,我的转换也是正确的?

4

1 回答 1

0

在运行时ClassCastException,如果问题与错误的转换有关(顺便说一下,引发异常的不是编译器,而是运行时。编译器/LINT 应该警告您有关“未经检查的转换”的问题)。

关于您的第二个问题,安全转换将在转换null不成功的情况下返回,这使您陷入 elvis 运算符 ( ?:) 的“else”分支,因此您将创建一个新的空HashMap<Int, Boolean>并将其分配给您的mCheatMap变量。这在您的第一个示例中不会发生,因为失败的强制转换会引发异常而不是简单地返回null,因此永远无法执行 elvis 运算符的“else”分支(您应该得到编译器/LINT 的另一个警告)。

于 2018-03-14T11:38:47.490 回答