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

时间:2017-08-22 07:55:46

标签: 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
        }
    }

为什么在第3行中!!必须有field运算符?

没有!!想法显示:

  

智能转换为'ByteArray'是不可能的,因为'field'是一个可变属性,可以在此时更改

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

使用上面的代码FindBugs警告:

  

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

     

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

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

2 个答案:

答案 0 :(得分:2)

bytesvar,它是可变的,可以在空检查后更改(可能在其他线程上)。您无法保证bytes非空,因此在此使用!!并不安全。

Official explanation

  

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

     
      
  • val 局部变量 - 始终;
  •   
  • val 属性 - 如果属性为private或internal,或者在声明属性的同一模块中执行检查。智能转换不适用于具有自定义getter的打开属性或属性;
  •   
  • var 局部变量 - 如果在检查和使用之间没有修改变量,并且没有在修改它的lambda中捕获;
  •   
  • var 属性 - 从不(因为其他代码可以随时修改变量)。
  •   

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

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

建议阅读:In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them

答案 1 :(得分:1)

您无法使用可空的可变属性进行智能投射,因为在此代码中:

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

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

您可以分配给本地val并进行智能播放:

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