《Effective Java》读书笔记二(通用方法)
2024-09-03 01:23:21
No8 覆盖equals方法时请遵守通用约定
通用约定,下面的约定前提都是x/y/z不为null值。
- 自反性(reflexive),x.equals(x)必须返回true。
- 对称性(symmetric),当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。
- 传递性(transitive),如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true。
- 一致性(consistent),信息没有修改的情况下,多次调用x.equals(y)的返回结果必须一致。
- x.equals(null)必须返回false。
诀窍:
- 使用“==”操作符检查“参数是否为对这个对象的引用”。
- 使用“instanceof”操作符检查“参数是否为正确的类型”。
- 把参数转换为正确的类型。
- 对于该类中的每个“关键(significant)”域,检查参数中的域是否与该对象中对应的域相匹配。
No9 覆盖equals方法时总要覆盖hashCode
“为不相等的对象产生不相等的散列码”,这正是hashCode约定中第三条的含义。计算hashCode示范代码:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber; return result;
}
31有个很好的特性,即用移位和减法来代替乘法,可以得到更好的性能:31*i == (i<<5)-i。现代的VM可以自动完成这种优化。
如果计算散列码的开销比较大,可以考虑缓存,只计算一次等方法。
No10 始终覆盖toString
“建议所有的子类都覆盖这个方法”。在实际应用中,toString方法应该返回对象中包含的所有值得关注的信息。
无论你是否决定指定格式,都应该在文档中明确地表明你的意图。示范:
/**
* Returns the string representation of this phone number.
* The string consists of fourteen characters whose format
* is "(XXX) YYY-ZZZZ", where XXX is the area code, YYY is
* the prefix, and ZZZZ is the line number. (Each of the
* capital letters represents a single decimal digit.)
*
* If any of the three parts of this phone number is too small
* to fill up its field, the field is padded with leading zeros.
* For example, if the value of the line number is 123, the last
* four characters of the string representation will be "0123".
*
* Note that there is a single space separating the closing
* parenthesis after the area code from the first digit of the
* prefix.
*/ @Override
public String toString() {
return String.format("(%03d) %03d-%04d",
areaCode, prefix, lineNumber);
}
No12 考虑实现Comparable接口
compareTo方法的通用约定与equals方法的相似:将这个对象与指定的对象进行比较。当该对象小于、等于或大于指定对象的时候,分别返回一个负整数、零或者正整数。如果由于指定对象的类型而无法与该对象进行比较,则抛出ClassCastException异常。
强烈建议(x.compareTo(y) == 0) == (x.equals(y)),但这并非绝对必要。
如果一个类有多个关键域,你必须从最关键的域开始,逐步进行到所有的重要域。
示范代码:
public int compareTo(PhoneNumber pn) {
// Compare area codes
int areaCodeDiff = areaCode - pn.areaCode;
if (areaCodeDiff != 0)
return areaCodeDiff; // Area codes are equal, compare prefixes
int prefixDiff = prefix - pn.prefix;
if (prefixDiff != 0)
return prefixDiff; // Area codes and prefixes are equal, compare line numbers
return lineNumber - pn.lineNumber;
}
最新文章
- [Android] 时间Time Date 以及Location中gettime
- Linux high memory 学习总结
- webstorm svn 报错
- [codevs1380]没有上司的舞会
- bzoj1231
- Map集合重要练习
- 输入输出函数 I/O函数之perror()
- wikioi 1034 家 实时动态的网络流量(费用流)
- UVa 10706 - Number Sequence
- C#数组--(一维数组,二维数组的声明,使用及遍历)
- [原] inline operator delete &; DLL boundary
- 比较对象--"=="与"equal"的区别
- 如何在自己设计的页面中调用metamask-1
- python3 练习题 day02
- Lua语言总结
- Android储存
- 用arm-linux-gnueabihf移植MP3播放器libmad-0.15.1b的时候出现错误提示
- pc端样式初始化
- Sass 基本特性-基础 笔记
- SSL 认证之后,request.getScheme()获取不到https的问题记录