M. *_*rov 8 java java-8 method-reference
我正在尝试重构以下代码:
class Base {
private Object a, b, <...>; // there's like 10 of these attributes of different type
public Object a() {
return a;
}
public Object b() {
return b;
}
// more getters like the ones above
}
class RootNode extends Base { }
class BranchNode extends Base {
private RootNode root; // passed via constructor
public Object a() {
Object value = super.a();
return value != null ? value : root.a();
}
public Object b() {
Object value = super.b();
return value != null ? value : root.b();
}
// below are more methods like the above one, all with same logic
}
Run Code Online (Sandbox Code Playgroud)
当然,我想删除此代码中的重复,以避免在添加新属性时键入更多相同的行,但我无法弄清楚如何执行此操作.
我的第一直觉是它看起来很像这个代码(不幸的是,它不能编译):
private <T> T nvlGet(Function<Base, T> accessor) {
T value = accessor.apply(super); // this is the problem line, because there is no way to pass a "super-reference" to anything
return value != null ? value : accessor.apply(root);
}
// and then public accessors would look like this:
public Object a() {
return nvlGet(Base::a);
}
Run Code Online (Sandbox Code Playgroud)
我无法通过调用accessor.apply(this)而不是"修复"上述代码accessor.apply(super),因为这会导致Stack Overflow错误.
到目前为止我设法提出的最近是使用绑定供应商,像这样:
private <T> T nvlGet(Supplier<T> first, Supplier<T> second) {
T value = first.get();
return value != null ? value : second.get();
}
public Object a() {
return nvlGet(super::a, root::a);
}
Run Code Online (Sandbox Code Playgroud)
然而,这是我在理想世界中所拥有的相同方法的两倍.所以,我想知道我是否遗漏了一些东西,我仍然能以某种方式修复使用的版本Function<Base, T>
不存在像 \xe2\x80\x9csuper 引用\xe2\x80\x9d 这样的东西会改变可重写方法(也称为invokevirtual指令)的普通调用的结果。
只要您坚持使用函数,使用两个方法引用的解决方案就是最好的解决方案,而传递评估值则更简单:
\n\nprivate <T> T nvlGet(T value, Supplier<T> second) {\n return value != null? value: second.get();\n}\npublic Object a() {\n return nvlGet(super.a(), root::a);\n}\nRun Code Online (Sandbox Code Playgroud)\n