尽管在“::”左边指向的是一个类(有点类似于静态方法引用),实际上它是指向一个对象,toString方法是Object类上的实例方法,不是静态方法。您可能不使用常规实例方法语法的原因是,还没有引用的实例。
在以前,当我们调用x::toString时,我们是知道x的类型,但是有些情况我们是不知道的,但你仍然可以传递一个方法引用,但是在后面使用此语法时需要提供对应的类型。
例如,下面的表达式等同于x没有限制的类型。
有两种不同的实例方法的引用基本是学术上的。有时候,你需要传递一些东西,其他时候,Lambda 的用法会为你提供。
这个例子类似于一个常规的方法引用;它这次调用String 对象的toString方法,该字符串提供给使用 Lambda 的函数,而不是从外部作用域传递的函数。
这个String看起来像是引用一个类,其实是一个实例。是不是有些迷惑,为了能清晰一些,我们需要看一个使用 Lambda 表达式的方法,如下:
public static String function(String value, Function<String, String> function) { return function.apply(value); }所以,这个 String 实例直接传递给了方法,它看起来像一个完全合格的Lambda。
public void lambdaExample() { function("value", x -> x.toString()); }上面的代码可以简写成String::toString, 它是在说在运行时给我提供对象实例。
如果你想用匿名类展开加以理解,它是这个样子的。参数x是可用的并没有被遮蔽,所以它更像是Lambda 表达式而不是闭包。
Oracle描述了四种类型的方法引用,如下所示。
种类 举例
静态方法引用 ContainingClass::staticMethodName
特定对象的实例方法引用 ContainingObject::instanceMethodName
特定类型的任意对象的实例方法引用 ContainingType::methodName
构造方法引用 ClassName::new
下面是方法引用的语法和具体的例子。
种类 语法 举例
静态方法引用 Class::staticMethodName String::valueOf
特定对象的实例方法引用 object::instanceMethodName x::toString
特定类型的任意对象的实例方法引用 Class::instanceMethodName String::toString
构造方法引用 ClassName::new String::new
最后,上面的方法引用等同于下面对应的 Lambda 表达式。
种类 语法 Lambda
静态方法引用 Class::staticMethodName (s) -> String.valueOf(s)
特定对象的实例方法引用 object::instanceMethodName () -> "hello".toString()
特定类型的任意对象的实例方法引用 Class::instanceMethodName (s) -> s.toString()
构造方法引用 ClassName::new () -> new String()
目前为止,Labmbda 的主要内容已经介绍完毕。