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)
!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With