根据Groovy文档,==
只是一个"聪明的";equals()
,因为它还负责避免NullPointerException
:
Java的
==
实际上是Groovy的is()
方法,Groovy的==
是一个聪明的equals()
![…]
但是,要进行通常的
equals()
比较,您应该更喜欢Groovy的==
,因为它还注意避免使用NullPointerException
,而与左侧或右侧是否为null
无关。
因此,如果对象不为null,则==
和equals()
应该返回相同的值。然而,在执行以下脚本时,我得到了意想不到的结果:
println "${'test'}" == 'test'
println "${'test'}".equals('test')
我得到的输出是:
true
false
这是一个已知的与GStringImpl
有关的错误还是我缺少的东西?
好问题,上面代码令人惊讶的是
println "${'test'}".equals('test')
返回CCD_ 15。另一行代码返回预期的结果,所以让我们忘记这一点。
摘要
"${'test'}".equals('test')
调用equals
的对象是GStringImpl
类型,而'test'
是String
类型,因此它们不被认为是相等的。
但是为什么
显然,equals
的GStringImpl
实现可以这样编写,即当它被传递一个包含与this
相同字符的String
时,它返回true。初步看来,这似乎是一件合理的事情
我猜它没有这样写的原因是因为它会违反equals
合同,该合同规定:
它是对称的:对于任何非null引用值x和y,x.equals(y)应返回true,当且仅当y.equals(x)返回true。
String.equals(Object other)
的实现在传递GSStringImpl
时总是返回false,因此如果GStringImpl.equals(Object other)
在传递任何String
时返回true,则违反对称要求。
在groovy中,a == b
首先检查compareTo
方法,如果存在compareTo
方法,则使用a.compareTo(b) == 0
。否则将使用equals
。
由于Strings和GStrings实现了Comparable
,因此有一个compareTo
方法可用。
如预期,以下打印结果为真:
println "${'test'}".compareTo('test') == 0
Groovy语言文档:中记录了==
的行为
在Java中,
==
表示对象的基元类型或标识相等。在Groovy中,==
意味着在所有情况下都是相等的。当为Comparable
对象计算相等性时,它转换为a.compareTo(b) == 0
,否则,它转换成a.equals(b)
。要检查身份(引用相等),请使用is
方法:a.is(b)
。从Groovy3中,您还可以使用===
运算符(或否定版本):a === b
(或c !== d
)。
Groovy语言文档中提供了运算符重载的完整列表:
操作员 | 方法 |
---|---|
+ | a.plus(b) |
- | a.减去(b) |
* | a.乘(b) |
/ | a.div(b) |
% | a.mod(b) |
** | a.功率(b) |
| | a.或(b) |
& | a.和(b) |
^ | a.xor(b) |
as | a.as类型(b) |
a() | a.调用() |
a[b] | a.getAt(b) |
a[b] = c | a.putAt(b,c) |
a in b | b.is案例(a) |
<< | a.leftShift(b) |
>> | a.右移(b) |
>>> | a.rightShiftUnsigned(b) |
++ | a.next() |
-- | a.以前() |
+a | a.正() |
-a | a.否定() |
~a | a.bitwiseNegate() |
将此作为附加答案留在这里,这样Groovy初学者就可以很容易地找到它。在比较之前,我将GString显式地转换为普通String
println "${'test'}".equals("test");
println "${'test'}".toString().equals("test");
中的结果
false
true