创建非捕获方法引用,它将调用超类方法

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>

Hol*_*ger 4

不存在像 \xe2\x80\x9csuper 引用\xe2\x80\x9d 这样的东西会改变可重写方法(也称为invokevirtual指令)的普通调用的结果。

\n\n

只要您坚持使用函数,使用两个方法引用的解决方案就是最好的解决方案,而传递评估值则更简单:

\n\n
private <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}\n
Run Code Online (Sandbox Code Playgroud)\n