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

时间:2019-05-14 10:13:34

标签: android kotlin android-bundle

让我们假设MainFlag的Activity中有一个非空的枚举enum class MainFlag { PARAM1, PARAM2 }对象(例如lateinit var):

private lateinit var flag: MainFlag

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

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

并且我曾经在一些活动中使用此flag并使用空检查

flag?.let{
  //..
}

但是Android Studio抱怨:

  

在类型为非空的接收器上的不必要的安全调用   MainActivity.Companion.MainFlag

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

3 个答案:

答案 0 :(得分:4)

是的,可以是null。之所以收到警告,是因为您将类型转换为不可为空的类型

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

应该是

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

答案 1 :(得分:0)

首先,您必须将变量声明为

private lateinit var flag: MainFlag?

private var flag: MainFlag? = null

然后您可以像这样设置flag的值

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

现在标记变量为nullable。因此,您需要在代码中的各处检查nullable,如下所示:

flag?.let{
  //..
}

答案 2 :(得分:0)

如果您确定intent?.extras?.getSerializable(ARG_FLAG)永远不会是null(并且也没有中间对象: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

...或保留TypeCastException时冒as MainFlag的风险。

Android Studio抱怨不必要的安全调用的原因是,您将类型指定为不可为空的MainFlag(通过as MainFlag广播间接指定)。因此,如果您访问flag,则它必须已经存在,并且不能为空(您是这样说的)。但是,如果涉及到null值,则代码将在转换时失败,即,对非空类型的转换将无法成功。