Kotlin不可变字段在调用时为null



这是代码片段:

abstract class SuperClass {
init {
toOverride()
}
abstract fun toOverride()
}
class ChildClass : SuperClass() {
private val innerClass = InnerClass()
override fun toOverride() {
innerClass.doSomething()
}
class InnerClass {
fun doSomething() = Unit
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val superClass = ChildClass()
superClass.toOverride()
}
}

调用superClass.toOverride((将导致null指针异常,但从ChildClass的角度来看,innerClass是一个不可变的字段。问题是在SuperClass的构造函数中调用了toOverride((。

在很多情况下,我们无法控制SuperClass的编写方式。例如,在android框架中有很多这样的情况http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/view/View.java#20160将在View.java的构造函数中调用。我们如何解决这些问题?添加null检查将触发IDE警告,并且如果您使用?,看起来kotlin编译器有时会修剪null检查?。运营商自以为?。没有必要。

首先,我读了构造函数中可重写的方法调用有什么问题?

这样一来,如果你真的无法控制父类做什么,并且你真的需要它做它正在做的事情,你可能可以做这样的事情(只显示ChildClass:

class ChildClass : SuperClass() {
private val innerClass: InnerClass? = InnerClass()
init {
// beware: this is ONLY done because toOverride ONLY calls
// innerClass.doSomething(), you have to make sure that anything else
// there is idempotent
toOverride()
}
override fun toOverride() {
innerClass?.doSomething()
}
}

我的建议是考虑是否有一个替代类层次结构的实现。

最新更新