如何在Java中优雅地实现类字段的增量更新操作?
Java原生语法不支持直接对私有字段使用+=这类快捷运算符,不过可以通过以下几种方案实现更简洁的增量更新写法:
- 方案1:在实体类中自定义增量方法
这种是性能最优、也最符合封装规范的实现方式,你可以给MyData类添加对应字段的增量方法:
@Data public class MyData { private long a; private long b; private long c; public MyData addA(long delta) { this.a += delta; return this; // 返回实例支持链式调用 } public MyData addB(long delta) { this.b += delta; return this; } public MyData addC(long delta) { this.c += delta; return this; } }
调用时直接写:
d.addA(2).addB(5).addC(8);
简洁度和其他语言的+=写法基本一致。
- 方案2:配合Lombok链式访问注解简化原有写法
如果你不想新增自定义方法,可以给类加@Accessors(chain = true)注解,让setter支持链式调用,相比原来逐行写的写法更紧凑:
@Data @Accessors(chain = true) public class MyData { private long a; private long b; private long c; }
调用代码:
d.setA(d.getA() + 2).setB(d.getB() +5).setC(d.getC() +8);
注:你给出的常规写法里d.getAC()属于笔误,应该为d.getC()。
- 方案3:封装通用工具方法适配所有实体类
如果需要增量更新的实体类很多,不想每个都加自定义方法,可以写一个通用的函数式工具方法:
// 通用增量工具方法 public static <T> void incr(ToLongFunction<T> getter, LongBiConsumer<T> setter, T obj, long delta) { setter.accept(obj, getter.applyAsLong(obj) + delta); } // 自定义基础类型消费接口,避免拆装箱损耗 @FunctionalInterface public interface LongBiConsumer<T> { void accept(T t, long value); }
调用时写法:
incr(MyData::getA, MyData::setA, d, 2); incr(MyData::getB, MyData::setB, d, 5); incr(MyData::getC, MyData::setC, d, 8);
不推荐为了简化写法直接把字段设置为public,会破坏类的封装性,后续如果要给字段增加赋值校验等逻辑时会非常难改造。
内容的提问来源于stack exchange,提问作者Jimmy Guo
相关产品推荐
相关产品推荐

