0x45
0x45

Reputation: 819

Nullsafe Long valueOf

Imagine the following scenario Long critId = Long.valueOf(criteriaIdentifier);

If the view is initially loaded criteriaIdentifier may be null, afterwards I set the value depending of the selectedItem in the JSF View.

However, Long.valueOf(criteriaIdentifier) throws a NumberFormatException - If the string cannot be parsed as a long(i.e null).

I've thought of default setting the Id to default -1, but I wanted to know if there is better practice .

PS: technically the criteriaIdentifier can't be -1, since these values are set from the Database, with a Sequence Generator, so I should know -1 was the default value and properly do the default operations

Upvotes: 14

Views: 31306

Answers (5)

msd.salehi
msd.salehi

Reputation: 1059

When we say nullSafe we usually expect to receive a null from the API when passing null to it, not a 0 or -1 or any other value.

The intention is that the API does not break in case of receiving null, but simply returning null.

For this, use createLong static method of the org.apache.commons.lang3.math.NumberUtils.

CAUSION*: This throws NumberFormatException if the input String is NOT null and is NOT numeric.

CAUSION**: since 3.1 it handles hex (0Xhhhh) and octal (0ddd) notations. N.B. a leading zero means octal; spaces are not trimmed.

Sample:

NumberUtils.createLong(null) --> null
NumberUtils.createLong("1") --> 1
NumberUtils.createLong("hi") --> NumberFormatException
NumberUtils.createLong(" 11") --> NumberFormatException (does not trim)
NumberUtils.createLong("023") --> 19 (leading 0 means octal)
NumberUtils.createLong("0x23") --> 35 (leading 0x means hex)

Upvotes: 8

Ehler
Ehler

Reputation: 325

You can use the NumberUtils from Apache Commons. It's null-safe and you can optionally specify a default value.

Example:

NumberUtils.toLong(null) = 0L
NumberUtils.toLong("")   = 0L
NumberUtils.toLong("1")  = 1L

NumberUtils.toLong(null, 1L) = 1L
NumberUtils.toLong("", 1L)   = 1L
NumberUtils.toLong("1", 0L)  = 1L

For more info, check the API.

Upvotes: 18

Mena
Mena

Reputation: 48404

Long.valueOf(null) will throw NumberFormatException, not NullPointerException.

In Java 8, you have the possibility to declaratively choose a default evaluation for a nullable inline, e.g.

Long.valueOf(
    Optional.ofNullable(criteriaIdentifier).orElseGet(() -> "-1")
)

It's a little verbose, but will allow you to default to -1l if criteriaIdentifier is null (no need for additional dependencies).

API here and here.

Upvotes: 4

Veselin Davidov
Veselin Davidov

Reputation: 7071

It depends on your scenario but usually there are ways to avoid such problems.

Generally setting IDs to -1 is a common practice but I don't think it is a good one. You know that -1 is not a possible value in your scenario but considering just the type Long it is a valid value. So everywhere in the code you will need to implement tests like if id!=-1 which makes the code harder to understand and generally the null value is more suitable for that scenario - Long object without a value.

If it was up to me for example in the method that receives an ID and waits a valid ID if I get null I would throw an exception and let the caller of the method handle that. If it is a web API for example (otherwise why would you get a String?) then you can throw an HTTP error. Or if you want to handle bad arguments then you better return null or use null as default value.

Upvotes: 1

Yeti
Yeti

Reputation: 1160

I'm assuming criteriaIdentifier is a String. You could use org.apache.commons.lang3.math.NumberUtils.toLong(String, long) which gives you the default value if the String argument is null. Or you use org.apache.commons.lang3.math.NumberUtils.toLong(String) which returns zero if the String is null.

Upvotes: 2

Related Questions