CptWasp
CptWasp

Reputation: 492

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?

Upvotes: 4

Views: 316

Answers (1)

isnot2bad
isnot2bad

Reputation: 24444

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)!

Upvotes: 9

Related Questions