我在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
答案 0 :(得分:2)
bytes
是var
,它是可变的,可以在空检查后更改(可能在其他线程上)。您无法保证bytes
非空,因此在此使用!!
并不安全。
请注意,当编译器无法保证变量在检查和使用之间无法更改时,智能强制转换不起作用。更具体地说,智能演员表适用于以下规则:
- 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
}
}