簡體   English   中英

java 中方法調用之前的空值檢查快捷方式

[英]Shortcut for null-check before method invocation in java

在編寫簡單或復雜的 java 代碼時,編寫如下代碼似乎很常見:

if (obj != null) {
    obj.someMethod();
}

或更具體:

Foo someValue = null;
if (valueObject != null) {
    someValue = valueObject.getSomeValue();
}

這意味着當值 Object 為 null 時, someValue保持 null。 現在,由於我經常遇到這種類型的代碼(並且它增加了認知/循環復雜性),我想知道是否有某種方法可以以任何方式簡化這些語句。 我尋找了一個看起來像這樣的解決方案:

Foo someValue = nullOrCompute(valueObject, valueObject::getSomeValue);

經過一些研究,Java 似乎沒有提供類似的功能。 因此,作為測試,我自己編寫了快捷方式,如下所示:

public class NullHelper
{
    private static <T> boolean check(T object)
    {
        return object == null;
    }

    public static <T> void nullOrExecute(T object, Consumer<T> func)
    {
        if (!check(object))
            func.accept(object);
    }

    public static <T, R> R nullOrCompute(T object, Function<T, R> func)
    {
        return check(object)
            ? null
            : func.apply(object);
    }

    public static <T, P0, R> R nullOrCompute(T object, BiFunction<T, P0, R> func, P0 param0)
    {
        return check(object)
            ? null
            : func.apply(object, param0);
    }

    // more params
}

請注意,如果您想包含具有更多參數的版本,則必須編寫自己的“ NFunction ”接口,因為 Java 不提供TriFunction或更高版本。

我的問題是:

這段代碼是簡化現有大型代碼庫的好方法嗎? 如果沒有,是因為有一個我不知道的更方便的 Java 功能,還是因為我需要改進我的自定義版本(以及如何改進)?

請記住,我不是在談論一般最方便的解決方案,而是針對可以應用於大型現有代碼庫的解決方案。

先感謝您。

你的代碼:

check(foo)
nullOrExecute(foo, consumer)
nullOrCompute(foo, mapper)
nullOrCompute(foo, func, param)

使用選項的等效代碼:

Optional.ofNullable(foo).isPresent();
Optional.ofNullable(foo).ifPresent(consumer);
Optional.ofNullable(foo).map(mapper)

考慮使用Optional<>而不是null來表示合法不存在的東西。

Optional<Bar> valueObject = getValueObject();
Optional<Foo> someValue = valueObject.map(o -> o.getSomeValue());

Optional<>有一些方法( mapifPresentorElseorElseGet )根據它是否具有值來采取不同的操作。

如果您希望將更改限制在較小的范圍內(一種方法,甚至一行),您仍然可以完成您正在尋找的內容,而無需編寫自定義實用程序方法。

Foo someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue).orElse(null);

但我想你會發現,如果你以這種方式開始, Optional<>范式會隨着時間的推移自然而然地傳播開來,並從整體上提高你項目的代碼質量。

Optional更快,並且允許鏈接不存在的字段。

完全使用遺留的可為空對象:

Foo someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue).orElse(null);

部分地:

Optional<Foo> someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue);

移植到選件:

Optional<Foo> someValue = valueObject.map(Bar::getSomeValue);

優點:

Optional<Baz> someValue = valueObject.map(Bar::getSomeValue).map(Fuz::getSub);

someValue.ifPresent(v -> ... non-null v);

代碼樣式檢查器現在可以很好地檢測可空值和不可空值。 也可以注釋非空值。 正如您對擴展 null 處理的預期一樣,您可能會逐漸轉向 Optionals。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM