如何避免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 } }