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

按照通常的java 8 lambda理解: 雙冒號無法就是方法調(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è)重要的知識點(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)文章
解決@Api注解不展示controller內(nèi)容的問題
這篇文章主要介紹了解決@Api注解不展示controller內(nèi)容的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。2022-01-01
Java實(shí)現(xiàn)AES加密和解密方式完整示例
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)AES加密和解密方式的相關(guān)資料,AES加密為最常見的對稱加密算法,是一種區(qū)塊加密標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)用來替代原先的DES,已經(jīng)被多方分析且廣為全世界所使用,需要的朋友可以參考下2023-10-10
Java開發(fā)工具-scala處理json格式利器-json4s詳解
這篇文章主要介紹了開發(fā)工具-scala處理json格式利器-json4s,文章中處理方法講解的很清楚,有需要的同學(xué)可以研究下2021-02-02
關(guān)于maven項(xiàng)目引入maven庫沒有的jar處理辦法
這篇文章主要介紹了關(guān)于maven項(xiàng)目引入maven庫沒有的jar處理辦法,在平時(shí)開發(fā)中,有些jar包是不存在maven中央庫中的,那么此時(shí)該如何解決才能方便后續(xù)處理呢,需要的朋友可以參考下本文2023-03-03
java實(shí)現(xiàn)時(shí)間控制的幾種方案
這篇文章主要介紹了java實(shí)現(xiàn)時(shí)間控制的幾種方案,本文從多個(gè)方面給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
在Spring boot的項(xiàng)目中使用Junit進(jìn)行單體測試
今天小編就為大家分享一篇關(guān)于spring boot使用Junit進(jìn)行測試,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12

