2021-05-31

How to make Kotlin use field instead of setter in non-primary constructors too

If I use a primary constructor to initialize a property, its setter won't be called:

open class Foo(open var bar: Any)

open class Baz(bar: Any) : Foo(bar) {
    override var bar: Any
        get() = super.bar
        set(_) = throw UnsupportedOperationException()
}
...
Baz(1) // works, no setter is called

This works too:

open class Foo(bar: Any) {
    open var bar: Any = bar // no exception in Baz(1)
}

But this doesn't:

open class Foo {
    open var bar: Any
    constructor(bar: Any) {
        this.bar = bar // UnsupportedOperationException in Baz(1)
    }
}

This can't even be compiled:

open class Foo(bar: Any) {
    open var bar: Any // Property must be initialized or be abstract
    init {
        this.bar = bar
    }
}

I'm asking because I need to make bar lateinit to be able doing this:

Baz(1) // works
Foo(2) // this too
Foo().bar = 3 // should work too

But this doesn't work in Kotlin:

// 'lateinit' modifier is not allowed on primary constructor parameters
open class Foo(open lateinit var bar: Any)

And there's no syntax like this:

open class Foo() {
    open lateinit var bar: Any
    constructor(bar: Any) {
        // instead of this.bar
        fields.bar = bar // or whatever to bypass the setter
    }
}

Any ideas how to solve this? (besides reflection, adding extra properties and delegates)



from Recent Questions - Stack Overflow https://ift.tt/2SLtrLu
https://ift.tt/eA8V8J

No comments:

Post a Comment