不抛出NPE的合约注释

问题描述 投票:0回答:1

我有这个方法来减少样板代码进行空检查

@Contract("_ -> !fail")
@Nullable
public static <T> T valueElseNull(@NotNull final Supplier<T> supplier) {
  try {
    return supplier.get();
  } catch (final NullPointerException npe) {
    return null;
  }
}

所以不要写:

object.setField(source.getFoo() != null ? source.getFoo().getBar() : null);

我可以简单地写:

object.setField(valueElseNull(() -> source.getFoo().getBar()));

但是 IntelliJ 仍然警告我

source.getFoo().getBar()
可能会抛出 NPE,虽然我知道这个方法可以处理这个问题。 我尝试使用如上所示的
@Contract
注释来修复该警告,但不幸的是,没有
!fail
这样的构造。

如何解决此警告? 或者这样的实用方法是否已经存在(例如在 Apache Commons 中)? 或者我不应该这样做,为什么不呢?

提前致谢!

java intellij-idea
1个回答
0
投票

捕获 NPE 通常不受欢迎,原因如下:

  • 这令人困惑/令人惊讶
  • 抛出和捕获异常的成本相对较高
  • 它可能掩盖其他问题
  • 不清楚在哪里引发异常(通过您的方法调用或调用堆栈深处的某个地方)

无论以上几点,您都需要供应商的注释,而不是您的方法。异常在供应商中抛出,并且仅在您的方法中捕获。

我会提出一种不同的方法:

@Nullable
public static <T, R> R withNullable(
    final T value,
    final Function<? super T, ? extends R> mapper) {
  final T value = supplier.get();
  return value != null
      ? mapper.apply(value)
      : null;
}

然后使用:

object.setField(withNullable(source.getFoo(), foo -> foo.getBar()));
object.setField(withNullable(source.getFoo(), Foo::getBar));
© www.soinside.com 2019 - 2024. All rights reserved.