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

根据groovy文档 ,==只是一个'聪明的'equals(),因为它也避免了NullPointerException。 所以,如果对象不为null,==和equals()应该返回相同的值。 但是,执行以下脚本时,我得到了意想不到的结果:

println "${'test'}" == 'test' println "${'test'}".equals('test') 

我得到的输出是

 true false 

这个例子可以在这里find。

这是一个已知的与GStringImpl有关的错误或者我错过了什么?

很好的问题,上面的代码令人惊讶的是

 println "${'test'}".equals('test') 

返回false 。 另一行代码返回预期的结果,所以让我们忘了这一点。

概要

 "${'test'}".equals('test') 

equals被调用的对象的types是GStringImpl'test'Stringtypes的,所以它们不被认为是相等的。

但为什么?

显然, equalsGStringImpl实现可能已经被写入,以便当它传递一个包含相同字符的String ,它将返回true。 Prima facie,这似乎是一个合理的事情要做。

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

它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才返回true。

当传递一个GSStringImpl时, String.equals(Object other)将总是返回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 

==的行为logging在这里 。

在Java中==意味着对象的基本types或标识相等。 在Groovy ==转换为a.compareTo(b)==0 ,如果它们是Comparable ,则a.equals(b) 。 为了检查身份,是有的。 如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() |