在 java 中调用方法之前进行空检查的快捷方式



在编写简单或复杂的java代码时,编写这样的代码似乎很常见:

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

或更具体:

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

这意味着当值对象为空时someValue保持空。现在,由于我经常遇到这种类型的代码(它增加了认知/循环复杂性(,我想知道是否有某种方法可以以任何方式简化这些语句。我寻找的解决方案如下所示:

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);

代码样式检查器现在可以精细地检测可为空值和非可为空值。还可以注释不可为空的内容。可以增量移动到 Optionals,就像您在扩展 null 处理中预期的那样。

相关内容

  • 没有找到相关文章

最新更新