8

I have a BigDecimal amount that I want to cast to Long if it is not null, but I got a java.lang.NullPointerException exception doing:

BigDecimal bgAmount = getAmount();

long totalSupplyFilterMin = 
              Optional.ofNullable(bgAmount.longValue()).orElse(Long.MIN_VALUE);
Mureinik
  • 297,002
  • 52
  • 306
  • 350
Nuñito Calzada
  • 4,394
  • 47
  • 174
  • 301

5 Answers5

7

Don't...use an Optional for what is a null check. Just expressly check for null and then dereference the object if it isn't 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. It is not a replacement for a null check.

Makoto
  • 104,088
  • 27
  • 192
  • 230
6

First of all you use Optional incorrectly. When bgAmount == null, then Optional.ofNullable(bgAmount.longValue()) throws NPE. Correct usages are:

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

or

Optional.ofNullable(bgAmount)
                   .map(BigDecimal::longValue)
                   .orElse(Long.MIN_VALUE);
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
1

it seems bgAmount is null so upon invoking bgAmount.longValue() the exception arises.

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

btw don't use ofNullable here as bgAmount.longValue() will never be null.

you probably wanted to do:

Optional.ofNullable(bgAmount).map(s -> s.longValue()).orElse(Long.MIN_VALUE);
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
1

If bgAmount is null, calling longValue on it will result in a NullPointerException. Note this has nothing to do with the optional, as this is called before you even apply the optional.

Instead, you can call map to safely apply this conversion:

long totalSupplyFilterMin = 
     Optional.ofNullable(bgAmount).map(BigDecimal::longValue).orElse(Long.MIN_VALUE);
Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

Generally we have a pattern for this in our code base, something like the code below, but it's not much different that Makoto's answer in this case:

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

The only difference in the number of times you read variable bgAmount, this code reads it once, as opposed of twice in the above answer (this is extremely rarely important, if ever - but I've build a habit writing code like this).

Eugene
  • 117,005
  • 15
  • 201
  • 306