Effective Java Item 9, is the CaseInsensitiveString example correct?
effective-java, java
Solution
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)`!
Problem
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?