Получить и установить методы, которые зависят от другого поля - PullRequest
0 голосов
/ 04 октября 2018

Я не знаю, как сформулировать это в заголовке.Что такое Kotlin эквивалент Java-кода здесь.Все мои попытки заканчивались с ошибкой или переполнением стека.Это происходит при сериализации с Джексоном.

public class Test {
    private String test1;
    private String test2;

    public String getTest1() {
        return test1;
    }

    public void setTest1(String test1) {
        this.test1 = test1;
    }

    public String getTest2() {
        return test2!=null? test2:test1;
    }

    public void setTest2(String test2) {
        this.test2 = test2;
    }
}

Код Kotlin ниже,

class Test(var test1: String? = "") {
    var test2: String?
        get() = if (StringUtils.isNotEmpty(test2)) test2 else test1
        set(test2Val) {
            test2 = test2Val
        }
}

Какие основы Kotlin мне не хватает?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

test2 в конечном итоге вызовет получателя.Вы можете посмотреть на полученный Java-код для справки.

В пользовательских методах получения и установки вместо него используется field.Таким образом, правильный код будет:

class Test(var test1: String? = "") {
    var test2: String?
        get() = if (StringUtils.isNotEmpty(field)) field else test1
        set(test2Val) {
            field = test2Val
        }
}

Примечание: это вызывает вторую проблему.Вы не инициализировали переменную, которую вы должны делать с vars.Если у вас есть val и пользовательский метод получения, который возвращает что-то еще (например, val x = ... get() = someOtherVar, это не выдает ошибку компилятора).Это не относится к var с, хотя.Однако, в вашем случае, использования = null (или альтернативно = "") должно быть достаточно.

Но так как вы сказали, что получаете StackOverflowErrors, а не ошибку, связанную с отсутствием инициализации, я предполагаю, что вы действительно инициализируете его, но просто не включили его в MCVE.Но если вы этого не сделали, это стоит отметить.


Кроме того, у Kotlin есть такие методы, как isNotEmpty() и isNotBlank(), которые заменяют необходимость в StringUtils.isNotEmpty(), и он называется как field.isNotEmpty().Обратите внимание, что здесь вы хотите сделать if(field?.isNotEmpty() == true) ..., потому что в итоге вы получите логическое значение Nullable.Это также означает, что он возвращает test1, если поле пустое или пустое.Вы также можете добавить isNotBlank, если захотите.

И вам не нужно объявлять сеттеры вручную, если они делают то же самое, что и сгенерированный.Если вы сделаете это, IDE, например IntelliJ, также предупредит вас и предложит удалить его.На самом деле не имеет значения, объявляете ли вы это вручную или нет, если это установщик по умолчанию, но это помогает вам написать немного меньше кода.

0 голосов
/ 04 октября 2018
class Test(var test1: String? = "") {
    var test2: String?
        get() = if (StringUtils.isNotEmpty(test2)) test2 else test1
        set(test2Val) {
            test2 = test2Val // here you are recursively setting the value of test2              
        }
}

Если вы хотите присвоить значение вспомогательному полю , оно должно быть

field = test2Val

В этом случае установщик будет бессмысленным, потому что если вы нене объявляйте, это будет иметь такое же поведение.Идея состоит в том, что field является частной собственностью, а get и set являются установщиком.Вы можете выбрать, что возвращать из метода получения, и что делать со значением, передаваемым в средство установки.

Другая проблема заключается в том, что test2 требуется начальное значение, в Java оно будет инициализировано по умолчанию.на null, но в Kotlin вы должны явно назначить начальное значение.Так, например, с пустой строкой:

class Test(var test1: String? = "") {
    var test2: String? = ""
        get() = if (StringUtils.isNotEmpty(test2)) test2 else test1
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...