如何避免Kotlin字段中的冗余空检查(FindBugs警告)

我在Kotlin的课上有个bytes

 var bytes: ByteArray? = null get() = when { field != null -> Arrays.copyOf(field, field!!.size) else -> field } set(value) { field = when { value != null -> Arrays.copyOf(value, value.size) else -> null } } 

为什么在第三行必须有一个!! 运营商的field

没有!! 想法显示:

智能转换为“ByteArray”是不可能的,因为'field'是一个可以改变的可变属性

条件(field != null)确保在body(右侧)中field是null。 或不? 或者它可以被重新分配为null? 这怎么可能?

使用上面的代码FindBugs警告:

在com.xy.Some.getBytes()中已知为null的com.xy.Some.bytes的冗余nullcheck

此方法包含对常量null的已知空值的冗余检查。

http://findbugs.sourceforge.net/bugDescriptions.html#RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE

bytes是一个可变的变量,可能会在空检查(也可能是其他线程)后更改。 你不能保证bytes是非空的,所以使用!! 这里不安全。

官方解释 :

请注意,当编译器无法保证变量不能在检查和使用之间变化时,智能转换不起作用。 更具体地说,智能演员适用于以下规则:

  • val局部变量 – 总是;
  • val属性 – 如果属性是私有的或者内部的,或者在声明属性的相同模块中执行检查。 智能转换不适用于打开属性或具有自定义获取者的属性;
  • var局部变量 – 如果变量在检查和用法之间没有被修改,并且没有在修改它的lambda中被捕获;
  • var属性 – 从不(因为变量可以随时由其他代码修改)。

其中一个解决方法是使用let

 get() = field?.let { Arrays.copyOf(it, it.size) } ?: field 

建议阅读: 在Kotlin中,处理可空值的惯用方法是什么,引用或转换它们

你不能使用可空的可变属性进行智能转换,因为在这个代码中:

  if (nullableMutableProp != null) { doSomethingWith(nullableMutableProp) } 

在第1行和第2行之间,其他代码可以将值更改为空。

你可以分配到一个本地val和聪明的转换:

 get() { val local = field return when { local != null -> Arrays.copyOf(local, local.size) else -> local } }