kotlin 如何在创建可能产生编译时警告或异常的对象时强制调用setter方法?

nwlqm0z1  于 2023-01-21  发布在  Kotlin
关注(0)|答案(1)|浏览(113)

假设我有一个类A,它之前看起来像这样:

class A(str:String){
  // body
}

现在,我想从构造函数中移除参数,而不是使用setter来设置该值,如下所示:

class A(){

 lateinit var str:String
 
 fun setStr(paramsString:String){
   str = paramsString
 }

}

因为我使用setter赋值,所以在创建该类的对象时,它不会给予我一个编译时异常。
所以,我尝试了下面这样的东西:

class A(){

 lateinit var str:String
 
 init{
  setStr(strValue:String)
 }

 fun setStr(paramsString:String){
   str = paramsString
 }

}

这个init块将在创建类A的对象之后执行,类A的对象将被调用setter方法,但我仍然希望在创建下面的类的对象以调用setter方法时发出警告或抛出异常。

c2e8gylq

c2e8gylq1#

这个

class A(public str:String){
  // body
}

我已经有一个二传手,因为你可以做

A("Bla"); println(a.str)

编译时错误可能需要一些类型检查(例如,String?允许null,String检查非null)
如果要在a.str="Blub"上执行代码,请执行以下操作:

class A(){
  var str:String = ""
    set(str) {
        // check some stuff here, throw Exception
        field = str  // if all is well
    }

}

您也可以对get()BTW执行类似的操作。
另一种设置方法是使用var a: String by Delegate.vetoable....和其他Delegate方法-让您可以高度控制设置新值时发生的情况。

class A {
    var str: String = ""
        set(str) {
            // check some stuff here, throw Exception
            field = str // if all is well
        }

    var observableDelegate: String by Delegates.observable("") { p, o, n ->
        println("property: [$p], Old: [$o], New [$n]")
    }

    var notNullValue: String by Delegates.notNull<String>()

    var vetoable: String by Delegates.vetoable("") { property, oldValue, newValue ->
        println("property: $property, old: $oldValue, new: $newValue")
        newValue != "bla" && oldValue < newValue
    }
}

fun main() {
    val a = A()

    a.observableDelegate = "blub"

    println("Set value ${a.observableDelegate}")

    runCatching { a.notNullValue }.onFailure {
        println("Like expected: value not set yet, exception: ${it.message}")
    }

    a.notNullValue = "fuddder"
    println("Now notNullValue is set: ${a.notNullValue}")

    println("Vetoable now: ${a.vetoable} - setting to \"a\"")
    a.vetoable = "a"
    println("Vetoable now: ${a.vetoable} - setting to \"b\"")
    a.vetoable = "b"
    println("Vetoable now: ${a.vetoable} - setting to \"a\" again - should not work")
    a.vetoable = "a"
    println("Vetoable now: ${a.vetoable}")
}

输出:

property: [var com.savinggrains.mwh.web.rest.A.observableDelegate: kotlin.String], Old: [], New [blub]
Set value blub
Like expected: value not set yet, exception: Property notNullValue should be initialized before get.
Now notNullValue is set: fuddder
Vetoable now:  - setting to "a"
property: var com.savinggrains.mwh.web.rest.A.vetoable: kotlin.String, old: , new: a
Vetoable now: a - setting to "b"
property: var com.savinggrains.mwh.web.rest.A.vetoable: kotlin.String, old: a, new: b
Vetoable now: b - setting to "a" again - should not work
property: var com.savinggrains.mwh.web.rest.A.vetoable: kotlin.String, old: b, new: a
Vetoable now: b

相关问题