7

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

0x45
  • 669
  • 3
  • 7
  • 24
  • `NumberFormatException` - If the string cannot be parsed as a long. Editted – 0x45 Apr 18 '18 at 08:23
  • If `null` is an expected value in some cases, perform a null check in before or sourround with try/catch – André Stannek Apr 18 '18 at 08:24
  • @AndréStannek it should be never NULL, and if it was, i perform a default action – 0x45 Apr 18 '18 at 08:26
  • Possible duplicate of [How to check if a String is numeric in Java](https://stackoverflow.com/questions/1102891/how-to-check-if-a-string-is-numeric-in-java) – Balázs Németh Apr 18 '18 at 08:26
  • Possible duplicate of [How to check a string contains only digits and decimal points?](https://stackoverflow.com/questions/24833364/how-to-check-a-string-contains-only-digits-and-decimal-points) – Shubhendu Pramanik Apr 18 '18 at 08:28
  • All the duplicate flags, did you even read my problem? – 0x45 Apr 18 '18 at 08:33

5 Answers5

11

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.

Jacob van Lingen
  • 8,337
  • 7
  • 43
  • 74
Ehler
  • 255
  • 2
  • 9
3

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.

Mena
  • 46,817
  • 11
  • 84
  • 103
  • is there a Java 7 solution to this too? – 0x45 Apr 18 '18 at 08:34
  • @0x45 unfortunately no, there isn't as such. `Optional` comes with Java 8. You can either build your own util or use external libraries (or just check for `null` explicitly and assigning a value). – Mena Apr 18 '18 at 08:35
  • 1
    You shouldn't use Optional this way, just use a ternary expression, or do an explicit null check using an if. – Mark Rotteveel Apr 19 '18 at 17:17
3

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

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)
msd.salehi
  • 649
  • 6
  • 12
2

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.

Yeti
  • 1,038
  • 21
  • 26
1

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.

Veselin Davidov
  • 6,963
  • 1
  • 14
  • 22