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'
是String
types的,所以它们不被认为是相等的。
但为什么?
显然, equals
的GStringImpl
实现可能已经被写入,以便当它传递一个包含相同字符的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() |