Kotlin: как использовать пользовательские сеттеры в основном конструкторе

Я не знаю, как сделать так, чтобы при создании объекта значения параметров "проходили через сеттеры" самое близкое, что я получил, это дублировать код, использовать один раз в создании объекта и еще раз в сеттер

      class User(var name: String, password: String, age: Int) {

    // IDK how use a custom setter in the primary constructor
    var password: String = if (password.length > 6) password else throw  IllegalArgumentException("Password is too short")
        set(value) {
            if(value.length > 6)
                field = value
            else
                throw IllegalArgumentException("Password is too short")
        }

    var age: Int = if (age > 18) age else throw IllegalArgumentException("Age must be 18+")
        set(value) {
            if(value > 18 )
                field = value
            else
                throw IllegalArgumentException("Age must be 18+")
        }

    override fun toString(): String {
        return "login: $name, password: $password, age: $age"
    }


}

fun main() {

    val user1 = User("User1", "swordfish", 20)
    println(user1)

    try{
        // This code throw a exception
        user1.password = "fish"
    }
    catch (e: IllegalArgumentException){
        println(e.message)
    }

    // Here we can see if password has changed
    println(user1)

    try{
        val user2 = User("U2", "swordfish", 2)
        println(user2)
    }
    catch (e: IllegalArgumentException){
        println(e.message)
    }
}

Я хочу иметь возможность проверять (через сеттер) параметры, которые передаются при создании объекта.

1 ответ

Может быть много подходов к этому, но вы не ошибаетесь.

Что бы я сделал, чтобы добиться того, что вы пытаетесь сделать, это использовать встроенный error()функция, которая выдает IllegalStateExceptionна JVM.

      class User(var name: String, password: String, age: Int) {


    var password: String = password
        set(value) {
            assertValidPassword(value)
            field = value
        }

    var age: Int = age
       set(value) {
           assertValidAge(age)  
           field = value
       }

    init {
         this.password = password
         this.age =age
    }

    override fun toString(): String {
        return "login: $name, password: $password, age: $age"
    }
    private fun assertValidAge(age: Int) {
       if (age <=18 ) error("Age must be 18+")
    }
    private fun assertValidPassword(password: String) {
        if(password.length <= 6) error("Password is too short")
    }
}

Что я сделал здесь:

  1. Я поместил логин проверки внутри функции, которую я могу повторно использовать как в установщике, так и в теле конструктора.
  2. Я добавил тело основного конструктора, указав init {}блокировать
Другие вопросы по тегам