是来自 intent?.extras 的非空对象吗?可为空?

Is a non-null object from intent?.extras? nullable?

让我们假设,lateinit var:

在 Activity 中有一个非空枚举 MainFlag 对象(如 enum class MainFlag { PARAM1, PARAM2 }
private lateinit var flag: MainFlag

Furtheron,我稍后会在 onCreate() 中得到它,例如:

flag = intent?.extras?.getSerializable(ARG_FLAG) as MainFlag

我曾经在 activity 的几个地方使用这个 flag 进行空检查

flag?.let{
  //..
}

但随后 Android 工作室抱怨:

Unnecessary safe call on a non-null receiver of type MainActivity.Companion.MainFlag

我不确定在没有空检查的情况下使用它,因为如果 intent?.extras? 失败,将不会设置标志,因此 null?

是的,它可以是 null。您收到警告是因为您向下转换为不可为空的类型

intent?.extras?.getSerializable(ARG_FLAG) as MainFlag

应该是

intent?.extras?.getSerializable(ARG_FLAG) as? MainFlag

首先你必须将变量声明为

private lateinit var flag: MainFlag?

private var flag: MainFlag? = null

那么你可以这样设置flag的值

flag = intent?.extras?.getSerializable(ARG_FLAG) as? MainFlag

现在标志变量是nullable。所以你需要像这样在代码中到处检查 nullable

flag?.let{
  //..
}

如果您确定 intent?.extras?.getSerializable(ARG_FLAG) 永远不会是 null(以及中间对象的 none:intentintent.extras),那么你可以保持一切不变,只使用 flag.let { ... 而不是 flag?.let { ....

如果其中任何一个有可能是 null,那么您必须使用 MainFlag? 类型作为您的标志,例如:

private var flag : MainFlag? = null // having null in place basically makes the lateinit meaningless and rightfully lateinit does not allow nullable types

flag = intent?.extras?.getSerializable(ARG_FLAG) as? MainFlag

...或在保持 as MainFlag.

时冒 TypeCastException 的风险

Android Studio 抱怨不必要的安全调用的原因是,您将类型指定为 non-nullable MainFlag(间接通过您的 as MainFlag-cast ).所以如果你访问 flag 它必须已经存在并且它必须是 not-null (你这么说的)。但是,如果涉及 null 值,则代码将在转换时失败,即转换为 non-nullable 类型无法成功。