说我们有
class A {
B method1 (C c) { ... }
}
方法参考的方法1的类型是什么?
这就是foo()
此方法的方法签名是什么?:
foo (A::method1);
注意:
我已经定义了一个界面
interface I {
B m (A a, C c);
}
似乎将foo声明为
是正确的void foo (I i) { }
(因为它与来电foo(A::method1)
匹配
--inside foo
你必须写b=i.m(a,c)
来表示b=a.method1(c)
)。
这是唯一的出路吗?
答案 0 :(得分:3)
方法引用和lambdas是目标类型,以匹配SAM interfaces。在您的情况下,它必须与I
匹配,因为这是foo
的参数类型。
答案 1 :(得分:1)
非正式解释:
请记住,方法引用可以被认为是一些lambda的替代语法,而lambdas都实现了一个或多个functional interfaces。
请记住,lambdas(目前)是一种以更简洁的形式编写一些单方法匿名类的方法;因此,lambdas总是可以简化为匿名类(但并不总是相反)。
所以
foo (A::method1);
可以成为
foo ((c) -> <body>);
可以缩减为匿名类:
foo (new Function<B>() {
<body>
});
这是一个匿名类,它是Function
的子类型因此,方法引用是它们所代表的任何功能接口的匿名子类型,因此参数的类型必须是相应的功能接口或其超类型之一。
JLS实际上有一个标题为“15.13.2。方法参考的类型”的部分,但措辞可能有点迟钝。简而言之:
如果符合以下情况,方法参考可用作T
类型:
T
是一种功能界面类型(第9.8节)void
Number
或子类型以与`B foo(函数f)答案 2 :(得分:1)
您可以使用现有的BiFunction
:
import com.jayway.restassured.path.json.JsonPath;
String json = "{\"fields\":{\"field1\":1,\"field2\":2,\"field3\":3,\"field4\":\"4\"}}";
// The value of the JsonPath object stays in the correct order: {"fields":{"field1":1,"field2":2,"field3":3,"field4":"4"}}
JsonPath jsonpath = new JsonPath(json);
// When using any of the JsonPath methods the order is messed up and returns: "{field4=4, field3=3, field2=2, field1=1}"
Object map = jsonpath.getMap("fields");
答案 3 :(得分:0)
我在这里承认,这个问题太复杂了,我没有尝试就回答,但我试图理解你的问题,从而提供了我对这种情况的理解 - 你的方法很好。基本上你在这里做了以下事情 -
A::method1
作为I.m
的实现 - 这也很好。A::method1
已经存在,你可以使用方法引用而不是lambda表达式 - 这也很好。c
,该参数在行foo
中b=i.m(a,c)
方法的正文中完成。此处用于c
的实际参数应传递给A::method1
。a
中的对象a.method1
仍然是任意,因为您指定Class::Method
而非Instance::Method