2 回答
TA贡献1775条经验 获得超11个赞
参数表达式被认为与潜在适用方法的适用性相关,
m除非它具有以下形式之一:
一个隐式类型的 lambda 表达式1。
一个不精确的方法引用表达式2。
[...]
所以:
verify("bar", tokens.get("foo", e -> String.valueOf(e)));在重载解析期间,隐式类型的 lambda 表达式e -> String.valueOf(e)从适用性检查中跳过 - 两种verify(...)方法都适用 - 因此存在歧义。
相比之下,这里有一些可行的示例,因为类型是明确指定的:
verify("bar", tokens.get("foo", (Function<Object, String>) e -> String.valueOf(e)));
verify("bar", tokens.get("foo", (Function<Object, String>) String::valueOf));1 - 隐式类型的 lambda 表达式是一个 lambda 表达式,其中推断出其所有形式参数的类型。
2 - 一个不精确的方法引用 - 一个有多个重载的方法。
TA贡献1818条经验 获得超7个赞
有String.valueOf(...)不同参数的多种实现。编译器不知道你要调用哪一个。编译器无法看到所有可能的方法实际上都返回 a String,因此调用哪个方法并不重要。由于编译器不知道返回类型是什么,因此它无法推断出Function<...,...>表达式的类型,因此它无法理解您手头是否会有 aFunction或其他东西,因此无法判断您是否想调用该get方法一个Function或一个Class。
如果您不String::valueOf使用 usee -> String.valueOf(e)那么编译器可以推断出更多,但它仍然不会理解您将始终返回 aString并因此将其解释为Function<Object, Object>您的verify方法有问题。
e -> e.toString我不完全理解,我不明白为什么编译器不能在String这里推断为返回类型。它推断Object并执行与前一个案例完全相同的事情。如果您将操作拆分为
String s = tokens.get("baz", e -> e.toString());
verify("bat", s); // line 21那么它就可以工作了,因为编译器可以R从s. 通过显式指定,它的工作方式相同R:
verify("bat", tokens.<String>get("baz", e -> e.toString())); // line 21String.class编译器很容易理解您要调用该get(Class)方法。
Object::toString因为编译器知道这将是一个Function<Object, String>.
添加回答
举报
