在方法引用上下文中如何在函数接口和函数之间解释参数和参数

时间:2019-07-09 08:02:22

标签: java

interface MyFunc<T> {
  boolean func(T v1, T v2);
}

class Foo {
  private int value;

  Foo(int v) { value = v; }

  boolean isGreater(Foo obj) {   <-- (*)
    return value > obj.value;    <-- (**)    
  }
}

class Demo {
  static <T> int counter(T[] vals, MyFunc<T> f, T v) {
    int count = 0;

    for (int i = 0; i < vals.length; i++)
      if (f.func(vals[i], v)) 
        count++;

    return count;
  }

  public static void main (String [] args) {
    int count;

    Foo[] values = new Foo[10];

    for (int i = 0; i < values.length; i++)
      values[i] = new Foo(i);

    count = counter(values, Foo::isGreater, new Foo(5));

    System.out.println("values bigger " + count);
  }
}

此代码具有isGreater(*)函数,该函数计算小于作为参数传递的值的值的数量。我的困惑是interface MyFunc<T>如何推断比较两个Foo实例变量值的此return语句(**)具有2个参数。为了更清楚地说明MyFunc<T>如何将(T v1, T v2)作为参数,并且与函数isGreater(Foo obj)的匹配,该函数将对类型Foo的引用作为参数。

1 个答案:

答案 0 :(得分:3)

请注意,isGreater instance 方法。您将如何调用Foo的实例方法?除了该方法所需的所有参数之外,您还需要一个Foo实例

对于isGreater,实际上需要两个Foo实例来调用它(即使它只需要1个Foo作为参数):

foo1.isGreater(foo2)
^^^^           ^^^^

还要注意,当您使用Foo::isGreater时,没有给它任何Foo实例来调用isGreater的情况!通常,这不适用于实例方法,但是Java语言设计人员看到了它的出现并允许这样做。

无论如何,您都需要一个Foo实例来调用isGreater,并需要另一个实例作为参数传递。因此,我们可以将isGreater作为这样的静态方法“重写”:

public static boolean isGreater(Foo foo1, Foo foo2) {
    return foo1.isGreater(foo2);
}

您调用isGreater的实例被“提升”为参数!这并不是真的要在后台进行,但这仍然可以解释为什么首先可以做到这一点。