在 Java 中,方法引用可用於建立功能介面的實例。但是,在某些情況下,當方法引用的傳回類型與 Consumer 介面的 Accept 方法不符時,可能會出現混亂。
考慮以下程式碼:
Consumer<String> lambda1 = s -> {}; Function<String, String> lambda2 = s -> s; Consumer<String> lambda3 = LambdaTest::consume; // but s -> s doesn't work! Function<String, String> lambda4 = LambdaTest::consume;
當您可能會預料到,將lambda3 指派給Consumer 應該會失敗,因為Consumer 方法的回傳類型(String) 與Accept 的預期void 類型類型不符
然而,令人驚訝的是,lambda3 的賦值成功了。這是因為設計決策允許以與呼叫方法相同的方式使方法適應功能介面。這意味著任何有傳回值的方法都可以指派給 Consumer,而其傳回值將被忽略。
當涉及到 lambda 表達式時,規則稍微複雜一些。 Lambda 表達式有兩種形式:
僅當當表達式求值為某個值時,第一種形式((args) -> expression) 是值相容的。如果沒有程式碼路徑嘗試傳回值,則第二種形式 ((args) -> { statements* }) 可以是 void 相容的。
表達式 s -> s 不相容 void,因為 s 不是語句。但是,具有副作用的表達式(例如方法呼叫)可以用作語句。這意味著像 s -> 這樣的表達式s.toString() 和 s -> i 可以是 void 相容的。
因此,在 LambdaTest::consume 的情況下,方法引用被分配給 Consumer 接口,因為 Consumer 方法可以被調用,並且它的返回值可以被忽略。即使回傳類型不匹配,這種設計決策也能實現方法和功能介面之間的適應性。
以上是為什麼可以將帶返回值的方法引用分配給 Java 中的消費者介面?的詳細內容。更多資訊請關注PHP中文網其他相關文章!