简体   繁体   中英

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM