scala.Any的scaladoc中,解释了运算符 == (或方法 == ):
表达式x == that
等同于 if(x eq null)that eq null else x.equals(that)
http://www.scala-lang.org/api/current/#scala.Any
对于AnyRef 的子类对象,我可以轻松理解它,没有看到任何奇怪的东西。
但是,对于AnyVal 的值(我的意思是Int
, Double , Long 等),上述定义有些棘手( 1 eq null ?如果我们不将 1 转换为java.lang.Integer,这不会编译)。另外, == 和 equals()的行为不同。
我将给出一些例子。
scala> 1 == 1
res0:Boolean = true
scala> 1 == 1.0
res1:Boolean = true
scala> 1 == 1.2
res2:Boolean = false
scala> 2 == BigInt(2)
res3:Boolean = true
scala> 2.0 == BigInt(2)
res4:Boolean = true
scala> 2 == BigInt(3)
res5:Boolean = false
到目前为止,没有什么奇怪的地方。但是如果我们使用 equals()方法进行相同的操作,
scala> 1 equals 1
res7:Boolean = true
scala> 1 equals 1.0
res8:Boolean = false
scala> 1 equals 1.2
res9:Boolean = false
scala> 2 equals BigInt(2)
res10:Boolean = false
scala> 2.0 equals BigInt(2)
res11:Boolean = false
scala> 2 equals BigInt(3)
res12:Boolean = false
因此,如果类型不同,则equals()始终返回false,而==测试它们是否表示相同的值(如果将它们转换为相同的类型)。
在AnyRef 的子类中,方法 == 和 equals()返回相同的结果。
scala> BigInt(2)== 2
res25:Boolean = true
scala> BigInt(2)== 2.0
res26:Boolean = true
scala> BigInt(3)== 2
res27:Boolean = false
scala> BigInt(2)等于2
res28:Boolean = true
scala> BigInt(2)等于2.0
res29:Boolean = true
scala> BigInt(3)等于2
res30:Boolean = false
那么,为什么对于AnyVal ,方法 == 和 equals()是不同的?
我使用的是Scala版本2.10.2(Java HotSpot(TM)64位服务器VM,Java 1.7.0_25)。
编辑1
我看到==不能直接覆盖,因为根据在Scala中编程,第2版,它被定义为类Any中的final方法。
编辑2
尽管有答案,但我的问题仍然存在。 我会留下这个问题打开。
在Java中,scala.Int 和 scala.Long 对应于Java的原始类型 int 和 long 。
在Java中, java.lang.Integer 和class Main {
public static void main(String[] args) {
System.out.println(String.valueOf(new java.lang.Integer(1).equals(1)));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(1L)));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(1.0)));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(new java.lang.Integer(1))));
System.out.println(String.valueOf(new java.lang.Integer(1).equals(new java.lang.Long(1))));
}
}
输出:
true
false
false
true
false
是的,它们的行为类似于Scala的AnyVal的equals()
方法。但是,为什么会这样呢?
Scala的AnyVal
的==
方法是否对应于Java的原始类型的==
方法?
Scala的AnyVal
的equals()
方法是否对应于Java的类类型的equals()
方法?
那么使用BigInt进行相等性测试呢?Java中没有对应的原始类型。
问题仍然存在...
编辑3
我从scaladoc中找到了一些信息。(http://www.scala-lang.org/api/current/index.html#scala.Int)
从Shadowed Implicit Value Members项的Implicit information中,我发现==
被重载用于Char
、Short
、Float
等等,
并且==
将调用隐式转换int2double
、int2float
或int2long
。
而equals()
仅针对Any
定义,它将调用隐式转换int2Integer
。
也就是说,Int.equals()
将与java.lang.Integer.equals()
相同。
一个问题仍然存在:
为什么AnyVal
的==
被重载了,而equals()
没有被重载?
==
方法和equals()
方法在AnyRef
类型的值中是相同的。我认为它们在AnyVal
类型的值中也应该是相同的。但实际上它们是不同的。然而,在我学习 Scala 的时候,我找不到任何关于这个问题的资料。那么,为什么==
和equals()
在AnyVal
中不是相同的呢?是否有相关规范说明? - Naetmulprintln(Double.NaN == Double.NaN) println(Double.NaN equals Double.NaN)
,我期望是 true 和 true,但实际上输出是 false true,不理解它,任何帮助将不胜感激!!! - Aamir