Yet another approach of doing that might look like this.
I would love if Java supported in-language macros so that such patterns might be wrapped in a macro call and then expanded to generated source code. Having no macros, that all can be put in methods and do the check-copy pattern at runtime:
public final class Patch {
private Patch() {
}
public static <T> void nonNull(final Supplier<? extends T> get, final Consumer<? super T> set) {
@Nullable
final T value = get.get();
if ( value != null ) {
set.accept(value);
}
}
public static void nonZero(final DoubleSupplier get, final DoubleConsumer set) {
final double value = get.getAsDouble();
if ( value != 0 ) {
set.accept(value);
}
}
}
Test:
@Data
@AllArgsConstructor
final class Customer {
private final String name;
private String phoneNumber;
private float outstandingBalance;
}
And the test:
@Test
public void test() {
final Customer customer = new Customer(null, "+123", 2);
final Customer newCustomer = new Customer("john-doe", null, 0);
Patch.nonNull(customer::getName, newCustomer::setName);
Patch.nonNull(customer::getPhoneNumber, newCustomer::setPhoneNumber);
Patch.nonZero(customer::getOutstandingBalance, value -> newCustomer.setOutstandingBalance((float) value));
Assertions.assertEquals(new Customer("john-doe", "+123", 2), newCustomer);
}
Note that tools like Lombok generate Java code at compile time, but being javac
plugins (see the @Data
and AllArgsConstructor
annotations) are black boxes that generate code themselves (equals()
, hashCode()
, toString()
, get***()
and set***()
methods + the all-args constructor for Customer
respectively) limiting to their current features only (+ requires IDE support to make it look nicer).
If you prefer Java Reflection that (may have) has higher runtime cost, take a look at Apache Commons BeanUtils that seem to do that job at runtime: Helper in order to copy non null properties from object to another
By the way, don't use float for outstandingBalance
-- use BigDecimal
or whatever precise. Why not use Double or Float to represent currency?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…