springboot源碼中this::selfInitialize怪異用法的含義解析
最近在看springboot源碼中有一段很怪異的代碼
private ServletContextInitializer getSelfInitializer() {
return this::selfInitialize;
}

按照通常的java 8 lambda理解: 雙冒號(hào)無法就是方法調(diào)用的另一中寫法,那么this::selfInitialize就是調(diào)用selfInitialize方法,但是這個(gè)方法不是返回void嗎,為什么getSelfInitializer方法調(diào)用了這個(gè)方法還能返回ServletContextInitializer,從而繼續(xù)執(zhí)行onStartup方法呢?
是不是覺得非常奇怪,很難理解。
于是,先簡單斷點(diǎn)調(diào)試一下,看一下getSelfInitializer方法返回值到底是什么:
從上面的getWebServer進(jìn)來:



可以看到initializers(也就是getSelfInitializer返回值,就是個(gè)數(shù)組)的元素類型是一個(gè)lambda表達(dá)式,它的入?yún)㈩愋褪?strong>AnnotationConfigServletWebServerApplicationContext

而AnnotationConfigServletWebServerApplicationContext的父類是ServletWebServerApplicationContext(也就是getSelfInitializer方法所在的類),其實(shí)也就是this

那么可以推斷this::selfInitialize相當(dāng)于是整個(gè)被作為參數(shù)傳遞給了lambda表達(dá)式
為什么會(huì)有這種用法呢?
@FunctionalInterface
public interface ServletContextInitializer {
void onStartup(ServletContext servletContext) throws ServletException;
}可以看到ServletContextInitializer是一個(gè)函數(shù)式接口:
這里提兩個(gè)重要的知識(shí)點(diǎn):
1. 函數(shù)式接口只能有一個(gè)方法。
2. Lambda表達(dá)式就是一個(gè)函數(shù)式接口的實(shí)例,Lambda表達(dá)式也是函數(shù)式接口所定義方法的實(shí)現(xiàn)
所以,考慮到getSelfInitializer方法的返回值是ServletContextInitializer,那么this::selfInitialize這種lambda表達(dá)式的寫法相當(dāng)于下面的匿名內(nèi)部類的代碼:
new ServletContextInitializer() {
@Override
void onStartup(ServletContext servletContext) throws ServletException {
selfInitialize(servletContext);
};
}this::selfInitialize是把selfInitialize方法作為整體作為參數(shù)傳遞給了lambda表達(dá)式,重寫了ServletContextInitializer接口的onStartup方法的內(nèi)部方法體。
所以,像this::${method}這種用法,通常是把method方法作為參數(shù)傳遞給lambda表達(dá)式,達(dá)到重寫函數(shù)式接口方法的目的,此時(shí)一定要看一下this::${method}所在方法的返回值類型,這個(gè)返回值類型就是函數(shù)式接口的類型。

總而言之: Lambda表達(dá)式的引入降低了代碼的可讀性,遠(yuǎn)沒有匿名內(nèi)部類(@override)那么清晰, java的函數(shù)式編程做的很爛,感覺就是一個(gè)生搬硬湊的破爛玩具,沒有javascript做的好。
到此這篇關(guān)于springboot源碼中this::selfInitialize怪異用法的含義的文章就介紹到這了,更多相關(guān)springboot this::selfInitialize用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mall整合SpringSecurity及JWT認(rèn)證授權(quán)實(shí)戰(zhàn)下
這篇文章主要為大家介紹了mall整合SpringSecurity及JWT認(rèn)證授權(quán)實(shí)戰(zhàn)第二篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Spring boot2基于Mybatis實(shí)現(xiàn)多表關(guān)聯(lián)查詢
這篇文章主要介紹了Spring boot2基于Mybatis實(shí)現(xiàn)多表關(guān)聯(lián)查詢,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Lucene實(shí)現(xiàn)多種高級(jí)搜索形式
這篇文章主要介紹了Lucene實(shí)現(xiàn)多種高級(jí)搜索形式的相關(guān)資料,需要的朋友可以參考下2017-04-04
Spring Boot 直接用jar運(yùn)行項(xiàng)目的方法
這篇文章主要介紹了Spring Boot 直接用jar運(yùn)行項(xiàng)目的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2018-02-02
javaweb實(shí)現(xiàn)注冊(cè)登錄頁面
這篇文章主要為大家詳細(xì)介紹了javaweb實(shí)現(xiàn)注冊(cè)登錄頁面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Java8 Stream Collectors收集器使用方法解析
這篇文章主要介紹了Java8 Stream Collectors收集器使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

