加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

jvm – 为什么我们不能将val属性覆盖为带有get而没有初始化的var

发布时间:2020-12-15 04:41:31 所属栏目:Java 来源:网络整理
导读:我刚刚开始学习Kotlin.我想知道为什么我们不能在重写的val属性上使用get()方法作为var而不初始化它.但是当被覆盖为val时,它可以在没有初始化的情况下工作. open class Foo { val y = 21 open val x: Int get() { return 10 * y }}class Bar : Foo() { overri
我刚刚开始学习Kotlin.我想知道为什么我们不能在重写的val属性上使用get()方法作为var而不初始化它.但是当被覆盖为val时,它可以在没有初始化的情况下工作.

open class Foo {
    val y = 21
    open val x: Int
        get() {
            return 10 * y
        }
}
class Bar : Foo() {
    override var x: Int = super.x * 10 //If overridden as val works without initialisation
        get() {
            return super.x * (super.x * 10)
        }
}
fun main(args: Array<String>) {
    val bar: Bar = Bar()
    println("${bar.x}")
}

如果我没有在Bar类中初始化x,则会给出编译器错误.必须初始化属性.但是当我打印bar.x时,它打印从重写的getter计算的值,但不打印初始化的getter.

解决方法

这种行为是由于Kotlin的 backing fields概念.正如文档中所写 –

A backing field will be generated for a property if it uses the default implementation of at least one of the accessors,or if a custom accessor references it through the field identifier.

由于重写的属性x现在是var,因此它具有如下所示的setter的默认实现.

override var x: Int = super.x * 10 
        get() {
            return super.x * (super.x * 10)
        }
        set(value) {
            field = value
        }

因此,在声明var时,必须使用某个值初始化支持字段,因为Kotlin中没有默认值的概念(例如,未初始化的Java对象采用空值).

另一个解决方案是使用这样的自定义setter –

override var x: Int // Now you can leave it uninitialized
            get() {
                return super.x * (super.x * 10)
            }
            set(value) {
                // Nothing happens
            }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读