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)容請搜索腳本之家以前的文章或繼續(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-06Spring boot2基于Mybatis實(shí)現(xiàn)多表關(guān)聯(lián)查詢
這篇文章主要介紹了Spring boot2基于Mybatis實(shí)現(xiàn)多表關(guān)聯(lián)查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Lucene實(shí)現(xiàn)多種高級(jí)搜索形式
這篇文章主要介紹了Lucene實(shí)現(xiàn)多種高級(jí)搜索形式的相關(guān)資料,需要的朋友可以參考下2017-04-04Spring Boot 直接用jar運(yùn)行項(xiàng)目的方法
這篇文章主要介紹了Spring Boot 直接用jar運(yùn)行項(xiàng)目的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2018-02-02Java8 Stream Collectors收集器使用方法解析
這篇文章主要介紹了Java8 Stream Collectors收集器使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08