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 21
String.class
編譯器很容易理解您要調用該get(Class)
方法。
Object::toString
因為編譯器知道這將是一個Function<Object, String>
.
添加回答
舉報