可选同时铸造

Optional and casting at the same time

我有一个 BigDecimal 金额,如果不是 null,我想将其转换为 Long,但我遇到了一个 java.lang.NullPointerException 异常:

BigDecimal bgAmount = getAmount();

long totalSupplyFilterMin = 
              Optional.ofNullable(bgAmount.longValue()).orElse(Long.MIN_VALUE);

首先你用错了Optional。当 bgAmount == null 时,Optional.ofNullable(bgAmount.longValue()) 将抛出 NPE。正确的用法是:

Optional.ofNullable(bgAmount)
        .orElse(BigDecimal.valueOf(Long.MIN_VALUE))
        .longValue();

Optional.ofNullable(bgAmount)
                   .map(BigDecimal::longValue)
                   .orElse(Long.MIN_VALUE);

似乎 bgAmount 为空,因此在调用 bgAmount.longValue() 时出现异常。

long totalSupplyFilterMin = Optional.ofNullable(bgAmount.longValue())
                                    .orElse(Long.MIN_VALUE);

顺便说一句,不要在这里使用 ofNullable,因为 bgAmount.longValue() 永远不会为空。

你可能想做的事:

Optional.ofNullable(bgAmount).map(s -> s.longValue()).orElse(Long.MIN_VALUE);

不要...使用 Optional 什么是空检查。只需明确检查 null 然后 取消引用对象(如果它不为空)。

BigDecimal bgAmount = getAmount();
long totalSupplyFilterMin = Long.MIN_VALUE;
if(bgAmount != null) {
    totalSupplyFilterMin = bgAmount.longValue();
}

You use Optional as a return value to indicate the absence of a value.不是空检查的替代品。

如果 bgAmountnull,对其调用 longValue 将导致 NullPointerException。请注意,这与可选无关,因为它在您应用可选之前被调用。

相反,您可以调用 map 来安全地应用此转换:

long totalSupplyFilterMin = 
     Optional.ofNullable(bgAmount).map(BigDecimal::longValue).orElse(Long.MIN_VALUE);

通常我们的代码库中有一个模式,类似于下面的代码,但在这种情况下 并没有太大不同:

long totalSupplyFilterMin = Long.MIN_VALUE;
BigDecimal bgAmount;
if ((bgAmount = getAmount()) != null) {
     totalSupplyFilterMin = bgAmount.longValue();
}

读取变量bgAmount的次数的唯一区别是,此代码读取一次,而不是上面答案中的两次(这非常很少重要,如果有的话 - 但我已经养成了编写这样的代码的习惯)。