Existe uma maneira melhor de valores clone de um objeto sem usar reflexão?

Jazzepi:

Tentando verificar de forma eficiente para ver se uma nova cópia do objeto tem quaisquer campos diferentes, e se o fizerem, atualizar os locais e fazer uma nota do mesmo. Se qualquer um dos campos mudar, então eu preciso para manter o objeto no banco de dados. Eu não quero fazer essa chamada, se eu não tiver que, portanto, o boolean.

Eu não conseguia pensar em uma maneira melhor de fazer isso sem o uso de reflexão, mas eu não quero usar a reflexão aqui por causa da falta de segurança apoiadas pelo compilador (teria referências seqüência de caracteres para os nomes de campo), e nem todos os campos são do mesmo tipo (eu tenho algumas Java 8 campos instantâneas lá).

O que eu realmente quero evitar é a contabilidade de ter que lembrar de adicionar ou subtrair de / para o método de sincronização quando os campos são modificados. Obviamente subtraindo não é um grande negócio, porque o método vai quebrar, mas a adição é assustador se alguém não se lembrar de atualizar o novo campo.

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;
}
shmosel:

Este pode ser um pouco exagerado, mas você pode usar lambdas para extrair os campos e executar um loop contra eles. Eu vou assumir que tem getters e setters para simplificar.

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;
}

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=184922&siteId=1
Recomendado
Clasificación