繁体   English   中英

声明为不可为空的 Kotlin 属性即使具有初始化值也是可为空的

[英]Kotlin property declared as non-nullable is nullable even if it has initialized value

这是非常有趣的情况。 我有一些 android 自定义视图。 它有一些属性 'state' 用于根据此属性更改复选框的可绘制状态。 如您所见,此属性被声明为不可为空,并且我使用默认值“State.Regular”对其进行了初始化。

class SomeCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatCheckBox(context, attrs) {

    sealed class State {
        object Regular : State()
        object Specific : State()
    }

    // todo: it will be nice to implement statesaving
    //       but it's okay for now
    var state: State = State.Regular
        set(value) {
            field = value
            refreshDrawableState()
        }

    override fun onCreateDrawableState(extraSpace: Int): IntArray =
        super.onCreateDrawableState(extraSpace + 1).apply {
            val stateAttrRes = when(state) {
                State.Specific -> R.attr.some_custom_view_specific
                State.Regular -> R.attr.some_custom_view_regular
            }

            View.mergeDrawableStates(this, intArrayOf(stateAttrRes))
        }
}

但是当我们要使用这个视图时,它会因为这个异常而崩溃:

kotlin.NoWhenBranchMatchedException

我曾尝试调试 when 表达式,我注意到在“onCreateDrawableState”方法中,它没有用默认值“State.Regular”初始化,而是用“null”初始化,这就是为什么我们有这个“NoWhenBranchMatchedException”。

你知道为什么这个属性用 null 初始化以及如何解决这个问题吗?

它不仅适用于 Kotlin。 你在 Java 中也有这个问题。 所以最好通过检查它不为空或设置默认值来忽略它。

OnCreateDrawableState 在 Kotlin 中的 init 块之前调用。 初始化后,您的属性将初始化

问题是AppCompatCheckBox的构造函数(调用onCreateDrawableState )在初始化属性的SomeCustomView之前调用。 如果您不需要自定义设置器,您可以使用lateinit并在onCreateDrawableState lateinit进行初始化; 有了它,请考虑这些解决方法(但对于仅此一个地方而言,它们可能太复杂了)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM