According to the Groovy docs, the == is just a "clever" equals() as it also takes care of avoiding NullPointerException:
Java’s
==is actually Groovy’sis()method, and Groovy’s==is a cleverequals()![...]
But to do the usual
equals()comparison, you should prefer Groovy’s==, as it also takes care of avoidingNullPointerException, independently of whether the left or right isnullor not.
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 Is this a known bug related to GStringImpl or something that I'm missing?
== is symmetric in groovy. While that table is super handy, it's a bit misleading as == isn't actually on it.
Thankfully, a different portion of the Groovy Language Documentation saves the day: Behaviour of == In Java == means equality of primitive types or identity for objects. In Groovy == translates to a. compareTo(b)==0, if they are Comparable, and a. equals(b) otherwise.
== is a relational operator which checks if the values of two operands are equal or not, if yes then condition becomes true. equals() is a method available in Object class and is used to compare objects for equality.
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.
In groovy a == b checks first for a compareTo method and uses a.compareTo(b) == 0 if a compareTo method exists. Otherwise it will use equals.
Since Strings and GStrings implement Comparable there is a compareTo method available.
The following prints true, as expected:
println "${'test'}".compareTo('test') == 0 The behaviour of == is documented in the Groovy Language Documentation:
In Java
==means equality of primitive types or identity for objects. In Groovy==means equality in all cases. It translates toa.compareTo(b) == 0, when evaluating equality forComparableobjects, anda.equals(b)otherwise. To check for identity (reference equality), use theismethod:a.is(b). From Groovy 3, you can also use the===operator (or negated version):a === b(orc !== d).
The full list of operators are provided in the Groovy Language Documentation for operator overloading:
| Operator | Method |
|---|---|
+ | a.plus(b) |
- | a.minus(b) |
* | a.multiply(b) |
/ | a.div(b) |
% | a.mod(b) |
** | a.power(b) |
| | a.or(b) |
& | a.and(b) |
^ | a.xor(b) |
as | a.asType(b) |
a() | a.call() |
a[b] | a.getAt(b) |
a[b] = c | a.putAt(b, c) |
a in b | b.isCase(a) |
<< | a.leftShift(b) |
>> | a.rightShift(b) |
>>> | a.rightShiftUnsigned(b) |
++ | a.next() |
-- | a.previous() |
+a | a.positive() |
-a | a.negative() |
~a | a.bitwiseNegate() |
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With