《Effective Java》第9条,CaseInsensitiveString示例是否正确?

4

我正在阅读这本书的第二版,第36页。我不理解对于对称问题的解决方案:

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

如果我有 CaseInsensitiveString cis= new CaseInsensitiveString("hello")String s="hello",它们的行为方式是不对称的。因为s.equals(cis) 返回 true,但 cis.equals(s) 返回 false...
我错过了什么?

1
你实际尝试过s.equals(cis)吗? - chrylis -cautiouslyoptimistic-
请分享在CaseInsensitiveString中如何重写equals()方法。这可能与那个有关。 - Savv
1个回答

9
解决方案是正确的,因为没有违反对称性。关于 s.equals(cis),你是错误的。它将在任何情况下返回 false,因为 String 内部测试其他对象是否也是 String 的实例,并且如果不是则返回 false。(而 CaseInsensitiveString 不扩展 String。)
因此,由于 s.equals(cis)falsecis.equals(s) 也是 false,所以对称性得到保证。
关于 instanceof 的附注
请注意,String#equals(Object o) 使用 o instanceof String 来检查其参数的类型。这仅在 Stringfinal 并且无法被子类化时才正确!否则,我们可以编写 String 的子类,以下情况将发生:
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

如果你的类不是最终版本,那么在equals(Object)中进行类型检查时,请使用this.getClass() == o.getClass()代替instanceof

是的,在示例中我错过了 CaseInsensitiveString 没有扩展 String...非常感谢。 - CptWasp
@user3022586 是的,那就是重点。我添加了一条旁注来解决这个问题。 - isnot2bad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接