最近才開始看 lambda expression
直接看程式碼都覺得很難看懂
有種必須以 compiler 的角度來看才知道
特別是 lambda 只要符合 function descriptor 都可編譯
但是 target type 會是什麼,第一時間還真不知道是什麼
然後在練習 method reference 時,有一個地方一直無法理解
請看下面程式碼部份的中文
另問,如果要問問題,有什麼比較好貼出程式碼的地方嗎?
js 常看到 js fiddle
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class MethodReference {
public static void main(String[] args) {
List<String> strList = Arrays.asList("a", "b", "x");
/* == anonymous class == */
System.out.println("== anonymous class ==");
strList.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.print(s + ",");
}
}); // a,b,x,
/*
* == lambda expression ==
* Consumer<String> abstract method: void accept(String s);
* function descriptor: str -> void
*/
System.out.println("\n== lambda expression ==");
strList.forEach( str -> System.out.print(str + ",") );
strList.forEach( str -> {} );
strList.forEach( str -> {return;} );
/* Error: incompatible types: bad return type in lambda expression */
// strList.forEach( str -> "[" + str + "]" );
這裡使用 lambda 時,回傳值非 void 時會編譯錯誤
我是用,因為 forEach() 要的是 Consumer
所以要符合 Consumer 的 function descriptor 去理解
/* == Class::staticMethod == */
System.out.println("\n== Class::staticMethod ==");
strList.forEach(MethodReference::staticPrint);
strList.forEach(MethodReference::xxx);
/* compile success?? */
strList.forEach(MethodReference::yyy);
這裡編譯也成功,參數數目對了,但是方法回傳值不為 void
那 lambda 不行,但是 method reference 卻可以
是什麼原因呢?
因為 method 的 signature 不包括 return type ?
/* Error: incompatible types: invalid method reference */
// strList.forEach(MethodReference::zzz);
// strList.forEach(MethodReference::www);
這裡也會編譯錯誤,因為 Consumer 的 function descriptor
參數列表只允許一個引數傳入
/* object::instanceMethod */
System.out.println("\n== object::instanceMethod ==");
MethodReference ref = new MethodReference();
strList.forEach(ref::instancePrint);
/**** Class::instanceMethod ****/
System.out.println("\n== Class::instanceMethod ==");
strList.forEach(System.out::print);
}
private static void staticPrint(String s) {
System.out.print(s + ",");
}
private void instancePrint(String s) {
System.out.print(s + ",");
}
private static void xxx(String s) {
}
private static String yyy(String s) {
return (s == null ? "" : s) + "...";
}
private static void zzz() {
}
private static void www(String s1, String s2) {
}
}