[英]Writing custom Lint rule to ensure null-check before every using to avoid NullPointerException
[英]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<>
有一些方法( map
、 ifPresent
、 orElse
和orElseGet
)根據它是否具有值來采取不同的操作。
如果您希望將更改限制在較小的范圍內(一種方法,甚至一行),您仍然可以完成您正在尋找的內容,而無需編寫自定義實用程序方法。
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.