为什么在 运行 以下代码时我没有收到消息 "no empty, please" 的运行时异常

Why am I am not getting a runtime exception with message "no empty, please" when running following code

当 运行 以下代码时,为什么我没有收到消息“请不要为空”的运行时异常: 代码:

class Car(val name: String, col: String) {
    val fuel = 100
    var color = col
        set(value) {
            if (value.isBlank()) {
                throw RuntimeException("no empty, please")
            }
            field = value
        }
}
fun main() {
    var car = Car("Maruti", "")
    println("Your car ${car.name} is of ${car.color}")
}

在您的示例中,您初始化了支持字段 directly。这意味着不会调用 setter。显然,这段代码将调用 setter:

car.color = ""

或者您可以在 Carinit 块内调用 setter class:

class Car(col: String) {
    ...
    init {
        color = col
    }
}

如果设置为空颜色,将抛出RuntimeException。

初始化对象时,不使用 setter。在您的 class 中,属性 color 的值将使用构造函数中的 col 参数直接初始化。

class Car(val name: String, col: String) {
    val fuel = 100
    // color is getting its initial value from the 
    // constructor directly. Setter won't be used here
    var color = col
        set(value) {
            if (value.isBlank()) {
                throw RuntimeException("no empty, please")
            }
            field = value
        }
}

在你的主函数中,你没有调用 setter。

fun main() {
    // here only arguments are being passed to the constructor
    var car = Car("Maruti", "")
    println("Your car ${car.name} is of ${car.color}")
}

但是,如果您尝试将 setter 与空字符串一起使用,则会抛出异常。

fun main() {
        // here only arguments are being passed to the constructor
        var car = Car("Maruti", "")

        // this line would call the setter and 
        // exception would be thrown 
        car.color = ""

        println("Your car ${car.name} is of ${car.color}")
}

如果你想在对象初始化期间验证参数,那么你可以使用 init 块来放置你的逻辑。 init块中的代码在对象第一次初始化时执行。在构造函数中传递的参数和先前初始化的属性(在构造函数中以及 init 块之前的行号)在 init 块的范围内。

class Car(val name: String, col: String) {

    init {
        if (col.isBlank()) throw RuntimeException("no empty, please")
    }

    val fuel = 100

    var color = col
        set(value) {
            if (value.isBlank()) {
                throw RuntimeException("no empty, please")
            }
            field = value
        }
}

由于 init 块中的验证,如果您尝试用空字符串初始化它,它会抛出 RuntimeException

进行这种验证的更惯用的方法是使用 Kotlin 标准库中的 require 函数。

init {
        require(col.isNotBlank()) {"no empty, please"}
}

require 将抛出 IllegalArgumentException 如果给定消息的检查结果为假。