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?
Nice question, the surprising thing about the code above is that
println "${'test'}".equals('test')
returns false
. The other line of code returns the expected result, so let's forget about that.
"${'test'}".equals('test')
The object that equals
is called on is of type GStringImpl
whereas 'test'
is of type String
, so they are not considered equal.
Obviously the GStringImpl
implementation of equals
could have been written such that when it is passed a String
that contain the same characters as this
, 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:
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
The implementation of String.equals(Object other)
will always return false when passed a GSStringImpl
, so if GStringImpl.equals(Object other)
returns true when passed any String
, it would be in violation of the symmetric requirement.