oracle Java 8 documentation定义了 4 种类型的方法引用,您可以使用它们来代替 Lambda 表达式。我想了解的是一种方法引用,描述为:“对特定类型的任意对象的实例方法的引用”,写为 ContainingType::methodName
。
我不确定我是否遗漏了什么,但对我来说更像是:
“引用功能接口(interface)抽象方法的第一个参数,假设它是ContainingType
类型”。我试图想出一些例子,其中这个“任意对象”是第二个参数,但当然它不会编译。
是否有官方引用编译器如何解析此对象?我的理解是否正确:
- 任意对象必须是函数接口(interface)抽象方法的第一个参数。
- 方法引用的签名必须与函数式接口(interface)抽象方法的签名相同,不带第一个参数。
因此具有抽象方法A method(B b, C c, D d)
的函数式接口(interface)只能传递实例方法引用x::methodImpl
或B::methodImpl
。例如,我无法传递 C::methodImpl
,它是类 C
的一个实例,其签名为 A methodImpl(B b, D d)
。
是否还有其他情况我遗漏了,这可能是 Oracle 以如此模棱两可的方式写这个的原因?
不,你的理解是正确的。您链接的文档暗示(但没有充分强调)给定一个需要 args a1, a2, a3, ...
的功能接口(interface),这种类型的方法引用等同于调用的 lambda a1.namedMethod(a2, a3, ...)
。
请注意,为了保持一致性,需要像这样的具体定义 - 给出了带有两个 String
参数的功能接口(interface)的链接文档示例 (String s1, String s2)
,您将如何确定行为是 s1.doThing(s2)
还是 s2.doThing(s1)
否则?
您可以在 the JLS 中精确找到它:
If the compile-time declaration is an instance method, then the arguments to the method invocation expression (if any) are the second and subsequent formal parameters of the invocation method. Otherwise, the arguments to the method invocation expression are the formal parameters of the invocation method.