Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effective Java Item 9, is the CaseInsensitiveString example correct?

I'm reading the second edition of the book, page 36. I don't understand the solution to the simmetry problem:

@override public boolean equals(Object o) {
    return o instanceof CaseInsensitiveString &&
        ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}

If I have the CaseInsensitiveString cis= new CaseInsensitiveString("hello") and the String s="hello" this behaves in a non-symmetric manner, because s.equals(cis) is true, but cis.equals(s) is false...

What am I missing?

like image 551
CptWasp Avatar asked Jan 11 '23 20:01

CptWasp


1 Answers

The solution is correct, because symmetry is not violated. You're wrong concerning s.equals(cis). It will return false in any case as String internally tests if the other object is also instanceof String and returns false if not. (And CaseInsensitiveString does not extend String.)

So as s.equals(cis) is false and cis.equals(s) is false, symmetry is given.

Sidenote about instanceof

Note that String#equals(Object o) uses o instanceof String to check the type of its argument. This is only correct because String is final and cannot be subclassed! Otherwise we could write a subclass of String and the following would happen:

String s = "Hello";
SubclassOfString sos = new SubclassOfString("Hello");
s.equals(sos) == true // as sos is instanceof String
sos.equals(s) == false // as s is NOT instanceof SubclassOfString

So if your classes are not final, use this.getClass() == o.getClass() instead of instanceof for type checking in equals(Object)!

like image 110
isnot2bad Avatar answered Jan 18 '23 22:01

isnot2bad