gpt4 book ai didi

java - 与 Java BigDecimal 比较 null BigDecimal

转载 作者:行者123 更新时间:2023-12-02 06:15:27 25 4
gpt4 key购买 nike

我有以下代码:

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).

scala> val z: BigDecimal = null
z: BigDecimal = null

scala> z == null
res0: Boolean = true

看起来不错。然而...

scala> import java.math.{BigDecimal => JBigDecimal}
import java.math.{BigDecimal=>JBigDecimal}

scala> val x: JBigDecimal = null
x: java.math.BigDecimal = null

在REPL中,赋值会抛出NPE:

scala> val y: BigDecimal = x
java.lang.NullPointerException
at scala.math.BigDecimal.toString(BigDecimal.scala:452)
at scala.runtime.ScalaRunTime$.scala$runtime$ScalaRunTime$$inner$1(ScalaRunTime.scala:324)
at scala.runtime.ScalaRunTime$.stringOf(ScalaRunTime.scala:329)
at scala.runtime.ScalaRunTime$.replStringOf(ScalaRunTime.scala:337)
at .<init>(<console>:10)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)

使用惰性变量会出现我主要担心的问题。

scala> lazy val y: BigDecimal = x
y: BigDecimal = <lazy>

scala> y == null
res1: Boolean = false

有什么建议吗?最后的比较是一个错误吗?我考虑过将这两个元素包装在选项中,但我首先想了解为什么会发生这种情况。

此外,比较这两个 BigDecimal 还会导致另一个(可能不同,但相关)异常

scala> z == y
java.lang.NullPointerException
at scala.math.BigDecimal.toLongExact(BigDecimal.scala:411)
at scala.math.BigDecimal$$anonfun$isValidLong$1.apply$mcV$sp(BigDecimal.scala:196)
at scala.math.BigDecimal.noArithmeticException(BigDecimal.scala:211)
at scala.math.BigDecimal.isValidLong(BigDecimal.scala:196)
at scala.math.BigDecimal.equals(BigDecimal.scala:190)
at scala.runtime.BoxesRunTime.equalsNumNum(BoxesRunTime.java:168)

我以前经常使用断言来获得更有趣的结果

重新设计的更具体的示例:

  test("Both cases should be true") {
val x: JBigDecimal = null
val y: JBigDecimal = null
x should be (null)
y should be (null)
x == y should be (true)

val i :BigDecimal = x
val j :BigDecimal = y

i == j should be (true)
}

但是,比较 i == j 时失败

此外,即使使用选项,通过隐式将 JBigDecimal 转换为 BigDecimal,我仍然得到 BigDecimal(null) 实例。

我测试了这个错误报告,当我运行 BigDecimalBug 时,断言失败。

到目前为止,我复制的唯一可以正常工作的方法如下:

it("test implicit conversions from null Java BigDecimal to Option[BigDecimal]"){
val x: JBigDecimal = null
val y: JBigDecimal = null
x should be (null)
y should be (null)
x == y should be (true)

val i :BigDecimal = x
val j :BigDecimal = y

implicit def convertJBigDecimalOption(javaBigDecimal: JBigDecimal): Option[BigDecimal] =
Option(javaBigDecimal) map { x => BigDecimal(x.toString) }

val p :Option[BigDecimal] = x
val q :Option[BigDecimal] = y

p should be('empty)
q should be('empty)
}

最佳答案

发生 NullPointerException 是因为 REPL 在 val 赋值之后调用 toString(),这会引发异常。这就是为什么它不使用延迟求值抛出异常,因为它当时不调用 toString()

scala.math.BigDecimal 是一个包含 java.math.BigDecimal 的类,但是 scala.math.BigDecimal 的实例持有空值本身并不是空引用。在您的示例中 (y.bigDecimal == null) 将计算为 true。

无论如何,Option 的创建都是有原因的,使用它而不是分配和检查 null 是一个更好的主意。

编辑:

做这样的事情:

val x : java.math.BigDecimal = null
BigDecimal(x) == BigDecimal(x)

.. 将抛出 NullPointerException 因为 BigDecimal 将不可避免地调用此:

def compare (that: BigDecimal): Int = this.bigDecimal compareTo that.bigDecimal

.. 比较包装的 java.math.BigDecimal,并且 compareTo 在发现 null 时抛出异常。

关于java - 与 Java BigDecimal 比较 null BigDecimal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21527555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com