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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何處理 Java 可選鏈中空值的日志記錄

如何處理 Java 可選鏈中空值的日志記錄

哆啦的時(shí)光機(jī) 2022-11-02 15:20:26
假設(shè)我正在使用選項(xiàng),并且我有:A a;....Optional.ofNullable(a)    .map(A::getB)    .map(B::getC)    .ifPresent(c -> ...) // do something with c但是,如果出于某種原因,我想在 B::getC 為空(或 a 為空)時(shí)記錄。有一些成語來處理這個(gè)問題嗎?我可以做一堆嵌套的 ifPresent 調(diào)用,但這非常冗長。我能想到的最好的方法是一個(gè) FunctionalHelper 類,它包裝了一些 Optional 方法并添加了其他方法來支持日志記錄(log4j):private static final Logger LOG = //...private static final FunctionalHelper FH     = new FunctionalHelper(LOG, Level.DEBUG);FH.ofNullable(a, Level.WARN, "You gave me a null A"))    .map(FH.logNull(A::getB, "b was null for a: {}", a-> FH.args(a.getName()))    .map(B::getC)    .ifPresent(c -> ...) // do something with c它有效,但感覺有點(diǎn)像一個(gè)螺栓固定的解決方案。是否有一些成語(或至少是標(biāo)準(zhǔn)庫)來處理這種事情?(我也想知道如何干凈地處理鏈中拋出的檢查異常,但也許這是一個(gè)單獨(dú)的問題。)更新:作為對(duì)@Ole VV 的回應(yīng),這里是可選的示例(更新2:我對(duì)其進(jìn)行了一些調(diào)整以匹配 log4j varags 供應(yīng)商語義,但具有功能:private static final FunctionalHelper FH  = new FunctionalHelper(LOG, Level.DEBUG);void foo(A someA) {    FH.ofNullable(someA, Level.WARN, "You gave me a null A")            .map(FH.logNull(A::getB, "B was null for A: {}", A::getName))            .map(FH.logNull(B::getC, "C was null for B: {}", B::getName))            .ifPresent(c -> { /* do something with c */});}這是一個(gè) If-else 實(shí)現(xiàn):void foo2(A a) {    if (a == null) LOG.debug("You gave me a null A");    else {        B b = a.getB();        if (b == null) LOG.debug("B was null for a: {}", a::getName);        else {            String c = b.getC();            if (c == null) LOG.debug("C was null for a: {}", b::getName);            else { /* do something with c */ }        }    }}我會(huì)說前者更容易閱讀。也更容易修改現(xiàn)有的可選鏈以在需要時(shí)添加一些東西。
查看完整描述

4 回答

?
桃花長相依

TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超8個(gè)贊

正如@Ole 所說, Optional 并不意味著:


與其創(chuàng)建一個(gè) Optional,不如創(chuàng)建一個(gè)單例流(我剛剛注意到 Stream::of 的存在)。


您失去了 Optional::map 僅在元素存在時(shí)執(zhí)行的便利性,因此您自己有過濾器空值:


A a;

Stream.of(a)

  .peek(e->{if(e == null){LOG.debug("You gave me a null A");}})

  .filter(e->e != null) //Now you have to handle null values yourself

  .map(A::getB)

  .peek(e->{if(e == null){LOG.debug("B was null for A "+a.getName());}})

  .filter(e->e != null)

  .map(B::getC)

  .peek(e->{if(e == null){LOG.debug("C was null for B"+a.getB().getName());}})

  .filter(e->e != null)

  .findFirst() // Optional from now on.

如果您從可選開始,您可以執(zhí)行以下操作:


Optional<A> optA;

Stream.of(optA.orElse(null))

stream 到 optional 的過渡是平滑的,而 optional 到 stream 則不是。


查看完整回答
反對(duì) 回復(fù) 2022-11-02
?
心有法竹

TA貢獻(xiàn)1866條經(jīng)驗(yàn) 獲得超5個(gè)贊

你不應(yīng)該使用這樣的結(jié)構(gòu)有兩個(gè)原因:

  1. 首先,你不應(yīng)該混搭nulland Optional。Optional真的是nullapi-wise 的替代品。當(dāng)你返回時(shí)null,你就有問題了。A::getB應(yīng)該返回一個(gè)Optional<B>,而不是一個(gè)null。好的,有時(shí)您可以從外部世界獲取 API,而您沒有動(dòng)手A::getB,所以如果是這種情況,您只需像這樣工作,但另一種方法是清理您的輸入。

  2. 其次,您不應(yīng)該記錄null值。如果你記錄null值,這意味著你有類似的問題NullPointerExceptions,這意味著你沒有得到你所期望的。所以這基本上意味著你應(yīng)該清理你的輸入!在開發(fā)的時(shí)候有這種語句是可以的,但是在生產(chǎn)中,你應(yīng)該能夠在a.getB()返回null和b.getC()返回null時(shí)區(qū)別對(duì)待。這些天來,使用調(diào)試器通常比使用那些關(guān)于哪個(gè)值是null.

這兩個(gè)問題都可以通過清理您的輸入來解決。清理您的輸入意味著您應(yīng)該將不屬于您的輸入映射到您的輸入。通常的答案是代碼重復(fù):API 代碼和您的代碼。嗯,是的:有 API 模型和你的模型,但它不是重復(fù)的代碼:一個(gè)被清理,另一個(gè)沒有!

但無論如何,使用簡單的包裝器完全可以實(shí)現(xiàn)您的期望。實(shí)際上,它與您編寫的內(nèi)容相似(即使您沒有顯示代碼),但我想您已經(jīng)找到了處理此問題的最佳方法:

static <T,U> Function<T, U> logIfReturnsNull(Function<? super T, ? extends U> function, String functionName) {

  return input -> {

    U result = function.apply(input);

    if (result == null) {

      log.debug("{} returned null for input {}", functionName, input);

    }

    return result;

  };

}

然后你像這樣使用它:


Optional.ofNullable(a)

  .map(logIfReturnsNull(A::getB, "A::getB"))

  .map(logIfReturnsNull(B::getC, "B::getC"))

  .ifPresent(c -> ...)


查看完整回答
反對(duì) 回復(fù) 2022-11-02
?
慕勒3428872

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超6個(gè)贊

您可以與返回一些默認(rèn)值Optional.orElseGet()的 a 一起使用(不確定我的類型是否完全正確)。Supplier<A>A


Supplier<A> nonNullASupplier = () -> {

    LOGGER.log("Invoking supplier because A was null");

    return new A();

}

然后在調(diào)用代碼中:


Optional.ofNullable(a)

    .orElseGet(nonNullASupplier)

    .map(A::getB)

    .map(B::getC)

    .ifPresent(c -> ...) // do something with c

同樣不是 100% 確定這里有什么類型A,B但這是基本思想。


查看完整回答
反對(duì) 回復(fù) 2022-11-02
?
暮色呼如

TA貢獻(xiàn)1853條經(jīng)驗(yàn) 獲得超9個(gè)贊

我不知道這是否適合你,但也許你可以使用空對(duì)象模式。


class NullA extends A {

  B getB() {

     return new NullB();

  }

}

class NullB extends B {

  C getC() {

     return new NullC();

  }

}

class NullC extends C {

}

然后使用orElseGet返回空對(duì)象:


Optional.ofNullable(a)

    .orElseGet(new NullA())

    .map(A::getB)

    .map(B::getC)


查看完整回答
反對(duì) 回復(fù) 2022-11-02
  • 4 回答
  • 0 關(guān)注
  • 182 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)