Groovy在GStringImpl上使用equals()和==的结果不同

Anu*_*ora 52 groovy equals gstring

根据groovy文档,==只是一个"聪明"的equals(),因为它还负责避免NullPointerException.因此,如果对象不为null,则==和equals()应返回相同的值.但是,我在执行以下脚本时遇到意外结果:

println "${'test'}" == 'test'
println "${'test'}".equals('test')
Run Code Online (Sandbox Code Playgroud)

我得到的输出是

true
false
Run Code Online (Sandbox Code Playgroud)

这方面的一个例子可以在这里找到.

这是一个与GStringImpl相关的已知错误还是我缺少的东西?

Dón*_*nal 62

不错的问题,关于上面代码的令人惊讶的事情是

println "${'test'}".equals('test')
Run Code Online (Sandbox Code Playgroud)

回报false.另一行代码返回预期结果,所以让我们忘记这一点.

摘要

"${'test'}".equals('test')
Run Code Online (Sandbox Code Playgroud)

equals被调用的对象是类型GStringImpl,'test'而是类型String,因此它们不被认为是相等的.

但为什么?

显然GStringImpl,equals可以编写实现,当传递String包含相同字符的那个时this,它返回true.初步看来,这似乎是一件合理的事情.

我猜这不是这样写的原因是因为它违反了equals合同,其中规定:

对称性:对于任何非空的参考值x和y,x.equals(y)的应返回true,当且仅当y.equals(x)返回真.

String.equals(Object other)传递a时GSStringImpl,实现总是返回false ,所以如果GStringImpl.equals(Object other)在传递any时返回true String,则会违反对称要求.

  • 一个重要的注意事项:Collection.contains和"in"运算符的实现将使用equals方法而不是compareTo.当它被埋在几层`['test']下面时,很难发现这种情况.contains("$ {'test'}")==> false` (4认同)

Dun*_*nes 45

在groovy中a == b首先检查compareTo方法,并a.compareTo(b) == 0compareTo方法存在时使用.否则会使用equals.

自Strings和GStrings实现以来,Comparable有一种compareTo方法可用.

正如预期的那样,以下打印为true:

println "${'test'}".compareTo('test') == 0
Run Code Online (Sandbox Code Playgroud)

这里==记录行为.

在Java中==意味着对象的基本类型或标识的相等性.在Groovy ==a.compareTo(b)==0,如果是Comparable,则转换为a.equals(b).为了检查身份,有is.例如a.is(b).

对于其他运营商,请参阅此表:http://docs.groovy-lang.org/docs/latest/html/documentation/#Operator-Overloading

如果以上链接再次中断,则为后代提供内联链接表.

| Operator | Method                  |
|----------|-------------------------|
| +        | a.plus(b)               |
| a[b]     | a.getAt(b)              |
| -        | a.minus(b)              |
| a[b] = c | a.putAt(b, c)           |
| *        | a.multiply(b)           |
| a in b   | b.isCase(a)             |
| /        | a.div(b)                |
| <<       | a.leftShift(b)          |
| %        | a.mod(b)                |
| >>       | a.rightShift(b)         |
| **       | a.power(b)              |
| >>>      | a.rightShiftUnsigned(b) |
| |        | a.or(b)                 |
| ++       | a.next()                |
| &        | a.and(b)                |
| --       | a.previous()            |
| ^        | a.xor(b)                |
| +a       | a.positive()            |
| as       | a.asType(b)             |
| -a       | a.negative()            |
| a()      | a.call()                |
| ~a       | a.bitwiseNegate()       |
Run Code Online (Sandbox Code Playgroud)