Есть ли лучший способ клонировать значения из объекта без использования отражения? - PullRequest
0 голосов
/ 14 ноября 2018

Попытка эффективно проверить, имеет ли новая копия объекта какие-либо другие поля, и если они есть, обновите локальные и запишите это.Если какое-либо из полей изменилось, мне нужно сохранить объект в базе данных.Я не хочу делать этот вызов, если мне не нужно, следовательно, логическое значение.

Я не мог придумать лучший способ сделать это без использования отражения, но я не хочуиспользуйте отражение здесь из-за отсутствия безопасности при поддержке компилятора (будет иметь строковые ссылки на имена полей), и не все поля имеют один и тот же тип (у меня там есть несколько полей Java 8 Instant).

ЧтоЯ действительно хочу избежать учета необходимости помнить, добавлять или вычитать из / в метод синхронизации при изменении полей.Очевидно, что вычитание не имеет большого значения, потому что метод сломается, но добавление страшно, если кто-то не помнит, чтобы обновить новое поле.

public boolean syncWithFieldsFrom(User currentUser) {
    boolean doesUserNeedUpdating = false;
    if (!StringUtils.equals(email, currentUser.email)) {
        email = currentUser.email;
        doesUserNeedUpdating = true;
    }
    if (!StringUtils.equals(firstName, currentUser.firstName)) {
        firstName = currentUser.firstName;
        doesUserNeedUpdating = true;
    }
    if (!StringUtils.equals(lastName, currentUser.lastName)) {
        lastName = currentUser.lastName;
        doesUserNeedUpdating = true;
    }
    if (!StringUtils.equals(fullName, currentUser.fullName)) {
        fullName = currentUser.fullName;
        doesUserNeedUpdating = true;
    }
    return doesUserNeedUpdating;
}

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Это может быть немного излишним, но вы можете использовать лямбды, чтобы извлечь поля и запустить цикл против них.Для простоты я предполагаю, что у вас есть геттеры и сеттеры.

private static class Field<T> {
    final Function<User, T> getter;
    final BiConsumer<User, T> setter;

    Field(Function<User, T> getter, BiConsumer<User, T> setter) {
        this.getter = getter;
        this.setter = setter;
    }

    boolean sync(User src, User dst) {
        T srcField = getter.apply(src);
        if (!Objects.equal(srcField, getter.apply(dst))) {
            setter.accept(dst, srcField);
            return true;
        }
        return false;
    }
}

private static final List<Field<?>> FIELDS = Arrays.asList(
        new Field<>(User::getEmail, User::setEmail),
        new Field<>(User::getFirstName, User::setFirstName),
        new Field<>(User::getLastName, User::setLastName),
        new Field<>(User::getFullName, User::setFullName));

public boolean syncWithFieldsFrom(User currentUser) {
    boolean updated = false;
    for (Field<?> f : FIELDS) {
        updated |= f.sync(currentUser, this);
    }
    return updated;
}
0 голосов
/ 14 ноября 2018

Для глубокого клонирования (клонирует всю иерархию объектов): Commons-lang SerializationUtils - используя сериализацию - если все классы находятся в вашем контролировать, и вы можете принудительно реализовать Serializable.

Java Deep Cloning Library - using reflection - in cases when the classes or the 
objects you want to clone are out of your control (a 3rd party library) and you can't 
make them implement Serializable, or in cases you don't want to implement Serializable.

Для мелкого клонирования (клонирует только свойства первого уровня): commons-beanutils BeanUtils - в большинстве случаев.

 Spring BeanUtils - if you are already using spring and hence have this utility on 
 the classpath.

 I deliberately omitted the "do-it-yourself" option - the API's above provide a good 
 control over what to and what not to clone (for example using transient, or String[] 
 ignoreProperties), so reinventing the wheel isn't preferred.

пожалуйста, смотрите ниже URL. может помочь вам получить представление.

Java: рекомендуемое решение для глубокого клонирования / копирования экземпляра

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...