gpt4 book ai didi

java - 在 getter 链之后安全地调用 setter,例如 foo.getX().getY().setZ(...);

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:14:49 27 4
gpt4 key购买 nike

如何在 getter 链之后安全地调用 setter,例如 foo.getX().getY().setZ(...);?例如,假设我有一个嵌套的 POJO,我希望能够设置一个嵌套对象的字段。

Foo foo = ...
foo.getX().getY().setZ(...);

我希望行为是这样的,如果 X 和 Y 不存在,那么它们会自动创建;否则它会重用现有对象。

换句话说,我希望它的行为等同于

Foo foo = ...
X x = foo.getX();
if (x == null) {
x = new X();
foo.setX(x);
}

Y y = x.getY();
if (y == null) {
y = newY();
x.setY(y);
}

y.setZ(...);

我想知道是否有使用反射/函数的技巧接近于此。

我还有以下限制:

  • 我不能修改任何类
  • 解决方案必须只知道公共(public) getter 和 setter,而不是私有(private)实例变量
  • 我希望 getter 仅在特定请求时才修改内部状态;我不希望 x = foo.getX() 修改 foo。

最佳答案

使用函数式编程。创建一个接受 getter、setter 和供应商作为默认值的方法,该方法返回一个封装您需要的逻辑的 getter:

public static <T, U> Function<T, U> getOrSetDefault(
Function<T, U> getter,
BiConsumer<T, U> setter,
Supplier<U> defaultValue) {

return t -> {
U u = getter.apply(t);
if (u == null) {
u = defaultValue.get();
setter.accept(t, u);
}
return u;
};
}

然后创建这些装饰 getter:

Function<Foo, X> getX = getOrSetDefault(Foo::getX, Foo::setX, X::new);
Function<X, Y> getY = getOrSetDefault(X::getY, X::setY, Y::new);

最后,将它们链接起来并应用作为参数传入您的 foo 实例的结果函数:

Foo foo = ...
getX.andThen(getY).apply(foo).setZ(...);

编辑: 这假定 XY 都有一个由 X::new 引用的无参数构造函数Y::new。但是您可以使用任何东西作为 Supplier,即已经创建的实例或方法的返回值等。

关于java - 在 getter 链之后安全地调用 setter,例如 foo.getX().getY().setZ(...);,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53315143/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com