[随笔] scala equals的奇怪事情

coollzh 2011-09-28
看看下面的单元测试:

@Test def testEquals()
{
val iVal :Int =20;
val lVal : Long = 20;
val dVal : Double = 20.0

assertTrue(iVal==lVal)
assertTrue(dVal == iVal)
assertEquals(lVal,iVal)
assertEquals(dVal,iVal)
assertTrue(dVal equals iVal)
assertTrue(lVal equals iVal)
}

大家觉得那些通过,那些不通过?
kidneyball 2011-09-28
== 都是 true
equals 都是 false

scala中 == 处理规则是:
----------------------------------------------------
1. Null值不会导致NullPointerException
2. 除了null之外,其他东西 == null 结果都为false
3. 所有对象 == 自身都为true

4. 如果左值 (x == y 中的x)的静态类型有可能是java的基础类型或其打包类型(Byte, Short, Int, Long, Float, Double, Char 等等会被编译为基础类型),跳到第5步

如果左值不可能是这些类型,直接返回 x.equals(y)的值

5. 如果左右值都是基础类型,则返回使用java中的==比较所得的结果

如果左右值都是相同的final类型(比如说,都是java.lang.Long),则返回x.equals(y)的结果。

所有其他情况,则会对左右值进行必要的打包(boxing)并调用BoxesRunTime类上的相应方法进行比较。(这个类提供了一堆静态方法用来处理Boxing的值,其中有好几个用于比较的方法,逻辑大体上跟BoxesRunTime.equals一样,Scala会选择使用合理的方法来避免重复前面已经做过的步骤)
---------------------------------------------------------

因此,iVal == dVal 直接等于java中的 20 == 20.0d,结果是true

java的基础类型没有equals方法,因此iVal equals dVal 相当于Integer.valueOf(20).equals(Double.valueOf(20.0d)),结果是false
coollzh 2011-09-29
kidneyball 谢谢,分析的透彻啊
Global site tag (gtag.js) - Google Analytics