【问题标题】:Nullsafe Long valueOfNullsafe Long valueOf
【发布时间】:2020-10-15 19:31:38
【问题描述】:

想象以下场景 Long critId = Long.valueOf(criteriaIdentifier);

如果最初加载视图时criteriaIdentifier 可能为空,之后我根据JSF 视图中的selectedItem 设置值。

但是,Long.valueOf(criteriaIdentifier) 会抛出 NumberFormatException - 如果字符串无法解析为 long(即 null)。

我曾想过将 Id 默认设置为默认 -1,但我想知道是否有更好的做法。

PS:从技术上讲,criteriaIdentifier 不能为 -1,因为这些值是从数据库中使用序列生成器设置的,所以我应该知道 -1 是默认值并正确执行默认操作

【问题讨论】:

标签: java parsing numberformatexception java.lang


【解决方案1】:

您可以使用来自 Apache Commons 的 NumberUtils。它是 null 安全的,您可以选择指定默认值。

例子:

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

更多信息,请查看API

【讨论】:

    【解决方案2】:

    Long.valueOf(null) 将抛出 NumberFormatException,而不是 NullPointerException

    在 Java 8 中,您可以以声明方式为可空内联选择默认评估,例如

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

    这有点冗长,但如果criteriaIdentifiernull,则允许您默认为-1l(不需要额外的依赖项)。

    API herehere

    【讨论】:

    • 是否也有 Java 7 解决方案?
    • @0x45 不幸的是,没有,没有这样的。 Optional 随 Java 8 一起提供。您可以构建自己的 util 或使用外部库(或直接检查 null 并指定一个值)。
    • 你不应该以这种方式使用 Optional,只使用三元表达式,或者使用 if 进行显式的 null 检查。
    【解决方案3】:

    当我们说 nullSafe 时,我们通常希望在通过它传递 null 时从 api 接收 null,而不是 0-1 或任何其他值。

    为此,请使用org.apache.commons.lang3.math.NumberUtilscreateLong 静态方法。

    原因*: 如果输入字符串不是 null 并且不是数字,则会引发 NumberFormatException。

    CAUSION**:从 3.1 开始,它处理十六进制 (0Xhhhh) 和八进制 (0ddd) 符号。注:前导零表示八进制;空格不会被修剪。

    示例:

    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)
    

    【讨论】:

      【解决方案4】:

      我假设条件标识符是一个字符串。 你可以使用 org.apache.commons.lang3.math.NumberUtils.toLong(String, long) 如果 String 参数为空,则为您提供默认值。 或者您使用org.apache.commons.lang3.math.NumberUtils.toLong(String),如果字符串为空,则返回零。

      【讨论】:

        【解决方案5】:

        这取决于您的情况,但通常有一些方法可以避免此类问题。

        通常将 ID 设置为 -1 是一种常见做法,但我认为这不是一个好的做法。您知道 -1 在您的场景中不是一个可能的值,但仅考虑 Long 类型它是一个有效值。因此,您需要在代码中的任何地方实现测试,例如 if id!=-1,这会使代码更难理解,通常null 值更适合这种情况 - 没有值的长对象。

        如果由我决定,例如在接收 ID 并等待有效 ID 的方法中,如果我得到 null,我会抛出异常并让方法的调用者处理它。例如,如果它是一个 Web API(否则你为什么会得到一个字符串?)那么你可以抛出一个 HTTP 错误。或者,如果您想处理错误的参数,那么您最好返回 null 或使用 null 作为默认值。

        【讨论】:

        • 服务等不关心输入的 ID。
        猜你喜欢
        • 1970-01-01
        • 2022-11-12
        • 2011-08-31
        • 1970-01-01
        • 2012-09-03
        • 2019-01-09
        • 1970-01-01
        • 1970-01-01
        • 2016-06-06
        相关资源
        最近更新 更多