Examples:
// Language: JAVA // expected cases assert 3 == 3 // basic equality assert 4L == 4 // long integer equals integer version // equality on reference 1 // A is a class that does not overload the equals method A a1 = new A(3); A a2 = new A(3); assert a1 != a2; // there are two different objects so they are different assert !a1.equals(a2); // the equals method is not overloaded, so the basic reference is used by the JVM A a3 = a1; // we put the reference to a1 in a3 assert a1 == a3; // now the reference are the same assert a1.equals(a3); // same as before the equals is not overloaded so the reference are used // B is a class that overload equals method, so that the method compares the internal value directly B b1 = new B(1); B b2 = new B(2); B b3 = new B(1); assert b1 != b2; // the references are still different assert b1 != b3; assert !b1.equals(b2); // the equals method is used, so we compare their internal value, '1' with '2' assert b1.equals(b3); // this is true because '1' == '1' // third part: the strings, in Java the string are stored natively in memory // and the String object have reference to the intern memory, // so the equals is quite the same as '==' String str1 = "hello world"; String str2 = "hello you"; String str3 = "hello world"; String str4 = "hell" + "o world"; // concatenation of strings resulting in the same string value assert str1 != str2; assert str1 == str3; assert str1 == str4;1 : String equality, Advance reference
This is what we expect in Java, not necessarily in other languages and that is the problem when we start with Groovy.
Grooy truth:
// Language: GROOVY // like before assert 3 == 3 assert 4L = 4 // but in groovy the equals is replace by == and == by "is" operator // for class that does not implement equals it's quite the same as Java // class that does not overload equals A a1 = new A(3) A a2 = new A(4) assert a1 != a2 // internally groovy use a1.equals(a2) assert !a1.is(a2) // the '==' equivalent of Java // class that overload equals method B b1 = new B(3) B b2 = new B(4) B b3 = new B(3) // same value B b4 = b1 // same reference // here the things get more normal for a non-Java developper assert b1 != b2 assert b1 == b3 // use equals, so compare internally the value assert b1 == b4 // the reference are the same, so the equals returns true assert !b1.is(b3) assert b1.is(b4) // same reference // the strings come back to normal behavior not like Java with its static memory table to store Strings value assert "hello world" == "hello world" assert "hello you" != "hello me" // ready for weirdest thing in Groovy ? // Let's go, when a class implements Comparable in Groovy, // the == is no more the method equals, but now, the compareTo that should return 0 ! // C is a class that implements Comparable and overload equals // compare method use the first value and the equals method the second C c1 = new C(3, 5) C c2 = new C(2, 5) C c3 = new C(3, 6) assert c1.equals(c2) // the second values are the same, 5 == 5 assert !c1.equals(c3) // 5 != 6 assert c1 != c2 // compare 3 and 2 => not 0 assert c1 == c3 // compare 3 and 3 If you are not aware of this, we would have lots of bug without knowing the source because it's hidden, so don't forget to be consistant between equals / compareToHere is the source code for the A, B, C classes, in groovy:
// Language: GROOVY class A { int val A(int _val){ this.val = _val } } class B { int val B(int _val){ this.val = _val } @Override public boolean equals(Object obj) { if(obj instanceof B){ B that = (C) obj if(this.val == that.val){ return true } } return false } } class C implements Comparable<C>{ int valEqual int valComparable C(int _valComparable, int _valEqual){ this.valEqual = _valEqual this.valComparable = _valComparable } @Override public boolean equals(Object obj) { if(obj instanceof C){ C that = (C) obj if(this.valEqual == that.valEqual){ return true } } return false } @Override public int compareTo(C that) { // <=> is a special groovy operator that replace .compareTo method // in this case we use to compare integer with the normal compareTo method return this.valComparable <=> that.valComparable } }Hope that will help you avoiding errors and understand the real Groovy Truth !
No comments:
Post a Comment