Effective Java 第8条的疑问

编程技术  /  houtizong 发布于 3年前   118

 

Symmetry—The second requirement says that any two objects must agree on

whether they are equal. Unlike the first requirement, it’s not hard to imagine vio-

lating this one unintentionally. For example, consider the following class, which

implements a case-insensitive string. The case of the string is preserved by

toString but ignored in comparisons:

// Broken - violates symmetry!

public final class CaseInsensitiveString {

private final String s;

public CaseInsensitiveString(String s) {

if (s == null)

throw new NullPointerException();

this.s = s;

}

// Broken - violates symmetry!

@Override public boolean equals(Object o) {

if (o instanceof CaseInsensitiveString)

return s.equalsIgnoreCase(

((CaseInsensitiveString) o).s);

if (o instanceof String)  // One-way interoperability!

return s.equalsIgnoreCase((String) o);

return false;

}

... // Remainder omitted

}

The well-intentioned equals method in this class naively attempts to interop-

erate with ordinary strings. Let’s suppose that we have one case-insensitive string

and one ordinary one:

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");

String s = "polish";

As expected,  cis.equals(s) returns  true. The problem is that while the

equals method in  CaseInsensitiveString knows about ordinary strings, the

equals method in  String is oblivious to case-insensitive strings. Therefore

s.equals(cis) returns false, a clear violation of symmetry. Suppose you put a

case-insensitive string into a collection:

List<CaseInsensitiveString> list =

new ArrayList<CaseInsensitiveString>();

list.add(cis);

What does list.contains(s) return at this point? Who knows? In Sun’s cur-

rent implementation, it happens to return false, but that’s just an implementation

artifact. In another implementation, it could just as easily return true or throw a

runtime exception. Once you’ve violated the equals contract, you simply don’t

know how other objects will behave when confronted with your object.

To eliminate the problem, merely remove the ill-conceived attempt to interop-

erate with String from the equals method. Once you do this, you can refactor the

method to give it a single return:

@Override public boolean equals(Object o) {

return o instanceof CaseInsensitiveString &&

((CaseInsensitiveString) o).s.equalsIgnoreCase(s);

}

 

这段话最后说改成的代码是

public final class CaseInsenstiveString {private final String s;public CaseInsenstiveString(String s) {if(s == null) {throw new NullPointerException();} this.s = s;}@Overridepublic boolean equals(Object o) {return o instanceof CaseInsenstiveString &&((CaseInsenstiveString) o).s.equalsIgnoreCase(s);}public static void main(String[] args) {CaseInsenstiveString cis = new CaseInsenstiveString("test");String s = "test";System.out.println(cis.equals(s));System.out.println(s.equals(cis));}}

 测试结果,cis为Test还是test都是false

疑问

那么他这里的说法的意思是 根本不让CaseInsentiveString和String进行比较(因为o instanceof CaseInsenstiveString就是false了),即类型不同怎么比都false

还是有其他意思?

 

从对称性来看,是成立了,但是这样的例子怎么感觉不是说的这个意思,请大家指点

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客