代碼重構,為了確保功能的等效性,梳理代碼時,發現如下代碼:

1 public SingleRespTTO fundI(SingleReqTTO request) throws Exception { 2 return handlerSingleReq((req, logInfo) -> { 3 4 // 業務操作 5 ....略.... 6 }, request); 7 } 8 9 public SingleRespTTO handlerSingleReq(BiConsumer<SingleReqTTO, SingleRespTTO> consumer, 10 SingleReqTTO request) throws Exception { 11 // 業務操作 12 consumer.accept(request, respTTO); 13 ....略.... 14 return respTTO; 15 }
問題:
fundI(SingleReqTTO request)方法實現很簡單:
直接調用handlerSingleReq(BiConsumer<SingleReqTTO, SingleRespTTO> consumer,SingleReqTTO request)方法並返回,而handlerSingleReq的參數1 consumer是個lambda表達式:
(req, logInfo) -> {
// 業務操作
....略....
}
1、lambda表達式的方法參數是啥
這個lambda表達式有2個參數:req, logInfo,這是哪來的?
2、方法執行順序是啥
lambda作為參數,包含有方法體(很明顯還是個內部實現),先執行該lambda的內部邏輯呢還是先執行的handlerSingleReq方法體呢?
解析:
lambda的三個概念:Function接口、BiFunction接口、Consumer接口分析
問題答案:
Java8 內置的四大核心函數式接口:
函數式接口 |
參數類型 | 返回類型 | 用途 |
Consumer<T> |
T |
void | 對類型為T的對象應用操作,包含方法 : |
Supplier<T> |
無 | T | 返回類型為T的對象,包含方法 : |
Function<T, R> |
T | R | 對類型為T的對象應用操作,並返回結果。結果是R類型的對象,包含方法 : |
Predicate<T> |
T | Boolean | 確定類型為T的對象是否滿足某約束,並返回boolean 值。包含方法 : |
函數式接口,具體請參考:
https://blog.csdn.net/chenshun123/article/details/78122467
https://www.cnblogs.com/knowledgesea/p/3163725.html
https://blog.csdn.net/qq_28410283/article/details/80618456
https://blog.csdn.net/qq_29848473/article/details/79554472
簡單一句話:只要是@FunctionalInterface 修飾的接口都是函數式接口,就可以通過lambda表達式簡化代碼(lambda最大的優勢就是簡潔的代碼)
查看代碼,這里調用的是,查看源碼如下:

1 @FunctionalInterface 2 public interface BiConsumer<T, U> { 3 4 /** 5 * Performs this operation on the given arguments. 6 * 7 * @param t the first input argument 8 * @param u the second input argument 9 */ 10 void accept(T t, U u); 11 12 /** 13 * Returns a composed {@code BiConsumer} that performs, in sequence, this 14 * operation followed by the {@code after} operation. If performing either 15 * operation throws an exception, it is relayed to the caller of the 16 * composed operation. If performing this operation throws an exception, 17 * the {@code after} operation will not be performed. 18 * 19 * @param after the operation to perform after this operation 20 * @return a composed {@code BiConsumer} that performs in sequence this 21 * operation followed by the {@code after} operation 22 * @throws NullPointerException if {@code after} is null 23 */ 24 default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) { 25 Objects.requireNonNull(after); 26 27 return (l, r) -> { 28 accept(l, r); 29 after.accept(l, r); 30 }; 31 } 32 }
解釋:
接口有一個 accept方法,必須自己實現,它接收兩個泛型參數,而另一個方法是默認實現好的方法;
簡單測試下:

1 public static void main(String[] args) { 2 BiConsumer<Integer,String> biconsumer = (x,y) -> { 3 int a = x + 2; 4 System.out.println(a);// 12 5 System.out.println("----"+y);// ----我愛你 6 }; 7 biconsumer.accept(10,"我愛你"); 8 9 System.out.println("-----執行andThen()方法--------"); 10 BiConsumer<Integer,String> afterBiconsumer = (x,y) -> { 11 int a = x + 8; 12 System.out.println(a);// 18 13 System.out.println("----"+y);// ----哇呀呀 14 }; 15 biconsumer.andThen(afterBiconsumer).accept(10,"哇呀呀"); 16 } 17 }
結論:
BiFunction接口暴露的accept方法必須實現,並且是執行的入口(默認實現的andThen()方法,如果調用會執行兩次accept方法,首先執行accept方法,然后執行傳入的BiConsumer引用對象的accept方法方法)
lambda表達式中,BiFunction接口實現體自己不會去執行,它只是實現了accept方法,只有手工去調用它的時候才會執行accept方法體的內容。。。
而且,它接受的2個參數,是調用的時候傳遞過去的,方法體中只是聲明為泛型。。。
一切都明了:
1、lambda方法參數是啥
handlerSingleReq方法中,consumer.accept(request, respTTO)調用了lambda的的accept方法,參數就在這傳遞
2、方法執行順序是啥
只有調用的時候才執行,handlerSingleReq方法順序執行,consumer.accept(request, respTTO)時執行lambda方法體中的內容...