第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Lambda 程序中的應(yīng)用

通過(guò)前面的內(nèi)容我們對(duì)于 Lambda 表達(dá)式以及函數(shù)式編程已經(jīng)有了一定的了解,對(duì)于集合方面的使用也有了概念,那么,在本節(jié)我們將從一個(gè)日志改造的例子出發(fā),探討下如何在我們的程序中更好地使用 Lambda 表達(dá)式。

Tips: 本節(jié)內(nèi)容有點(diǎn)分散,主要是啟發(fā)大家的思路

1. 讓我們的類(lèi)支持 Lambda 表達(dá)式

日志記錄工具是我們平時(shí)用的最多的一個(gè)工具,比如 SLF4J、Log4j 等,可以幫助我們快速查看程序的信息、定位問(wèn)題,也在一定程度上增加了系統(tǒng)開(kāi)銷(xiāo),通常我們?cè)趯?xiě) debug 日志的時(shí)候?yàn)榱私档蜁?huì)進(jìn)行日志級(jí)別的判定 (在本例中我們使用的是 Log4j 2)

public class DemoLogger {
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(DemoLogger.class);
        if(logger.isDebugEnabled()){
            logger.debug("這是一個(gè)debug日志");
        }
    }
}

想必上面的代碼應(yīng)該都非常熟悉,在 Log4j 2 中提供了 Lambda 表達(dá)式實(shí)現(xiàn)的日志記錄方法,對(duì)于上述代碼我們可以簡(jiǎn)化為:

public class DemoLogger {
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(DemoLogger.class);
        logger.debug(()->"這是一個(gè)debug日志");
    }
}

通過(guò)查看源代碼我們可以發(fā)現(xiàn) Logger 對(duì)象提供了一個(gè) Supplier 的 debug 方法:

@Override
public void debug(final Supplier<?> msgSupplier) {
    logIfEnabled(FQCN, Level.DEBUG, null, msgSupplier, (Throwable) null);
}

@Override
public void logIfEnabled(final String fqcn, final Level level, final Marker marker, final Supplier<?> msgSupplier,
        final Throwable t) {
    if (isEnabled(level, marker, msgSupplier, t)) {
        logMessage(fqcn, level, marker, msgSupplier, t);
    }
}

在這個(gè)方法中,它通過(guò) logIfEnabled 判斷是否為 debug 進(jìn)而決定是否調(diào)用 supplier 對(duì)象的內(nèi)容。 這給了我們一個(gè)啟發(fā),那就是:

我們可以運(yùn)用 java.util.funciton 中的接口來(lái)重新封裝我們?cè)械念?lèi)來(lái)支持 Lambda 表達(dá)式,進(jìn)而簡(jiǎn)化我們的代碼。

2. 多重繼承

在 Java 中接口是允許多重繼承的,那么如果多個(gè)接口有著相同的默認(rèn)方法的情況下會(huì)怎么樣呢?

public class MultipleInterface {
    public interface RedBox{
        public default String color(){
            return "red";
        }
    }

    public interface BlueBox{
        public default String color(){
            return "blue";
        }
    }

    public class CombineBox implements RedBox,BlueBox{

    }
}

在上面的代碼中,我們定義了兩個(gè)接口 RedBoxBlueBox 都有相同的默認(rèn)方法 color,類(lèi) CombineBox 同時(shí)實(shí)現(xiàn) RedBoxBlueBox,此時(shí),由于編譯器不清楚應(yīng)該繼承哪個(gè)接口,所以報(bào)錯(cuò):

MultipleInterface.CombineBox inherits unrelated defaults for color() from types MultipleInterface.RedBox and MultipleInterface.BlueBox

此時(shí),我們可以使用同方法重載來(lái)明確方法內(nèi)容,當(dāng)然我們可以通過(guò) super 語(yǔ)法來(lái)給編譯器明確使用哪一個(gè)默認(rèn)接口:

public class CombineBox implements RedBox,BlueBox{
    public String color(){
        return RedBox.super.color();
    }
}

上述的內(nèi)容我們主要是對(duì)默認(rèn)方法的工作原理做了一個(gè)簡(jiǎn)單的介紹,對(duì)于默認(rèn)方法通常有三條定律來(lái)幫助我們使用默認(rèn)方法:

  1. 類(lèi)勝于接口:如果在繼承鏈中有聲明的方法,那么就可以忽略接口中定義的方法 (這樣可以讓我們的代碼向后兼容);
  2. 子類(lèi)勝于父類(lèi):如果一個(gè)接口繼承了另外一個(gè)接口,而且兩個(gè)接口都定義了一個(gè)默認(rèn)方法,那么子類(lèi)中定義的方法將生效;
  3. 如果上述兩條都不適用,那么子類(lèi)要么需要實(shí)現(xiàn)該方法,要么將該方法聲明成抽象方法 ( abstract )。

小結(jié)

本節(jié)從類(lèi)的重新和接口繼承兩方面介紹了我們?nèi)绾沃匦路庋b我們的類(lèi)來(lái)支持 Lambda 表達(dá)式,以及在函數(shù)接口在多繼承的情況下出現(xiàn)默認(rèn)方法沖突時(shí)如何去編寫(xiě)我們的代碼。大家可以在平時(shí)的編碼過(guò)程中按照上述的思路逐步練習(xí)封裝自己原來(lái)的代碼,自然就會(huì)有自己的心得體會(huì)。