According to the groovy docs, the == is just a 'clever' equals() as it also takes care of avoiding NullPointerException. So, the == and equals() should return the same value if the objects are not null. However, I'm getting unexpected results on executing the following script:
println "${'test'}" == 'test'
println "${'test'}".equals('test')
The output that I'm getting is
true
false
An example of this can be found here.
Is this a known bug related to GStringImpl or something that I'm missing?
In groovy
a == b
checks first for acompareTo
method and usesa.compareTo(b) == 0
if acompareTo
method exists. Otherwise it will useequals
.Since Strings and GStrings implement
Comparable
there is acompareTo
method available.The following prints true, as expected:
The behaviour of
==
is documented here.For other operators see this table: http://docs.groovy-lang.org/docs/latest/html/documentation/#Operator-Overloading
Linked table provided inline for posterity, in case the above link breaks again.
Nice question, the surprising thing about the code above is that
returns
false
. The other line of code returns the expected result, so let's forget about that.Summary
The object that
equals
is called on is of typeGStringImpl
whereas'test'
is of typeString
, so they are not considered equal.But Why?
Obviously the
GStringImpl
implementation ofequals
could have been written such that when it is passed aString
that contain the same characters asthis
, it returns true. Prima facie, this seems like a reasonable thing to do.I'm guessing that the reason it wasn't written this way is because it would violate the
equals
contract, which states that:The implementation of
String.equals(Object other)
will always return false when passed aGSStringImpl
, so ifGStringImpl.equals(Object other)
returns true when passed anyString
, it would be in violation of the symmetric requirement.