所以我在这里看到了大量的答案,坦率地说,它们过于复杂,这是一种保守的说法。
答案很简单:**::被称为方法引用。在Method References中,如果向下滚动到表格,可以找到所有的信息。
现在,让我们来简单了解一下什么是方法引用:
A::b在一定程度上替代了以下内联lambda表达式:(parameters…)-> A.b(parameter…)
要将此与您的问题联系起来,有必要理解Java lambda表达式。这并不难。
内联lambda表达式类似于已定义的函数接口(即具有不多于一个方法的接口)。
让我们来看看我的意思:
InterfaceX f = (x) -> x*x;
InterfaceX必须是功能接口。任何函数接口,对于编译器来说,InterfaceX唯一重要的是你定义了格式:
InterfaceX可以是以下任何一种:
interface InterfaceX
{
public Integer callMe(Integer x);
}
或:
interface InterfaceX
{
public Double callMe(Integer x);
}
或者更一般的说法:
interface InterfaceX<T, U>
{
public T callMe(U x);
}
让我们以第一个例子和前面定义的内联lambda表达式为例。
在Java 8之前,你可以这样定义它:
InterfaceX o = new InterfaceX(){
public int callMe(int x)
{
return x*x;
}
};
功能上是一样的。不同之处在于编译器如何感知它。
现在我们已经了解了内联lambda表达式,让我们返回到方法reference(::)。假设你有一个这样的类:
class Q {
public static int anyFunction(int x)
{
return x + 5;
}
}
由于方法anyFunctions与InterfaceX callMe具有相同的类型,我们可以用一个方法引用来等效这两个方法。
我们可以这样写:
InterfaceX o = Q::anyFunction;
这就相当于:
InterfaceX o = (x) -> Q.anyFunction(x);
方法引用的一个很酷的优点是,在将它们分配给变量之前,它们都是无类型的。因此,您可以将它们作为参数传递给任何具有相同外观(具有相同定义类型)的函数接口。这正是你的情况。