|
1 | 1 | ---
|
2 |
| -title: effectivejava |
| 2 | +title: Methods Common to All Objects |
3 | 3 | draft: false
|
4 | 4 | authors: [huyi]
|
5 | 5 | date: 2024-09-25
|
6 |
| -slug: effectivejava |
| 6 | +slug: effectivejava-chapter3 |
7 | 7 | description: Effective-Java阅读笔记
|
8 | 8 | 以下所言,或来自读书笔记,或来自书籍的勾画,或只是回忆...作为参考。
|
9 | 9 | categories:
|
10 | 10 | - 技术书籍
|
11 |
| - - 笔记 |
12 |
| - - Java |
| 11 | + - 学习笔记 |
| 12 | + |
13 | 13 | ---
|
14 | 14 |
|
15 |
| -阅读effective-java总结的一些笔记,先把书读厚,再把书读薄! <!-- more --> |
| 15 | +effective-java阅读笔记,第三章——对象的通用方法 <!-- more --> |
16 | 16 |
|
17 | 17 | # Chapter 3. Methods Common to All Objects
|
18 | 18 |
|
@@ -107,29 +107,62 @@ categories:
|
107 | 107 | hash值的生成还要考虑以下几点:
|
108 | 108 |
|
109 | 109 | 1. **不要试图从散列码计算中排除重要字段**,以提高性能;这**会导致不好的hash分布,影响散列表的性能**
|
110 |
| - |
111 | 110 | 2. 若一个类是**不可变**的,并且**散列码的计算成本很高**,可以考虑在对象中**缓存散列码**
|
112 | 111 |
|
113 |
| - ```java |
114 |
| - private int hashCode; // Automatically initialized to 0 |
115 |
| - @Override |
116 |
| - public int hashCode() { |
117 |
| - int result = hashCode; |
118 |
| - //no cache |
119 |
| - if (result == 0) { |
120 |
| - result = Short.hashCode(areaCode); |
121 |
| - result = 31 * result + Short.hashCode(prefix); |
122 |
| - result = 31 * result + Short.hashCode(lineNum); |
123 |
| - hashCode = result; // set cache |
124 |
| - } |
125 |
| - |
126 |
| - return result; |
127 |
| - } |
128 |
| - ``` |
| 112 | +```java |
| 113 | +private int hashCode; // Automatically initialized to 0 |
| 114 | +@Override |
| 115 | +public int hashCode() { |
| 116 | + int result = hashCode; |
| 117 | + //no cache |
| 118 | + if (result == 0) { |
| 119 | + result = Short.hashCode(areaCode); |
| 120 | + result = 31 * result + Short.hashCode(prefix); |
| 121 | + result = 31 * result + Short.hashCode(lineNum); |
| 122 | + hashCode = result; // set cache |
| 123 | + } |
| 124 | + |
| 125 | + return result; |
| 126 | +} |
| 127 | +``` |
129 | 128 |
|
130 | 129 | 3. **不要为hashCode返回的值提供详细的规范,这样客户端就不能理所应当的依赖它,这也为你以后可能的更改留有余地。**Java库中很多类,e.g. String和Integer,都将hashCode返回的确切值指定为实例值,这不是一个好主意,它阻碍了未来版本中提高散列算法的能力
|
131 | 130 |
|
132 | 131 |
|
133 | 132 |
|
| 133 | +## Item12. 始终覆盖toString方法 |
| 134 | + |
| 135 | +> 本条目讨论覆盖toString方法的好处是什么,为什么一定要覆盖 |
| 136 | +
|
| 137 | +toString的通用约定:返回的字符串应该符合**"简洁但信息丰富,易于阅读"**。 |
| 138 | + |
| 139 | +覆盖toString方法的好处及一些覆盖的建议: |
| 140 | + |
| 141 | +- **更易于使用**(被打印时更好的展示),使用该类的系统也**更易于调试**(日志错误消息中更好的展示) |
| 142 | +- toString返回的信息中应该**包含最适合该类的表示形式**,e.g. Phone类应该返回"xxxx-xxxx-xxxx"这种格式的内容,若类的对象很大且包含不利于展示的内容,toString应该返回一个**摘要信息** |
| 143 | +- 决定**是否对toString返回的内容指定<font color="red">格式</font>** |
| 144 | + - 优点:作为类的**标准的、明确的**表示,**可以作为输入或输出**,还可以提供一个匹配的静态工厂(valueOf)或构造器,来达到对象及其字符串标识之间来回的切换,e.g. java中BigInteger和大多数包装类就是这样实现的。 |
| 145 | + - 缺点:一旦指定则必须**终生使用**它,若你的类被广泛使用,则后续修改toString的格式将会破坏引用该类的代码和数据。若不选择格式,增加了在后续版本中添加信息或改进格式的灵活性 |
| 146 | +- 指定/不指定格式,你都**应该为toString提供详细的文档注释** |
| 147 | +- **提供对toString返回值中包含的信息的程序性访问(即getter方法)**,否则引用者不得不通过解析toString来获取他们的值,这种方式会让系统脆弱 |
| 148 | +- **在任何抽象类中编写toString方法**,并让子类共享公共的字符串表示形式 |
| 149 | + |
| 150 | + |
| 151 | + |
| 152 | +## Item13. 明智的覆盖clone |
| 153 | + |
| 154 | +若想调用Object.clone()方法来实现克隆,则类必须实现Cloneable接口,否则将抛出CloneNotSupportedException异常。 |
| 155 | + |
| 156 | +如果不是通过Object.clone()方法实现克隆的,则不需要实现Cloneable接口。如下: |
134 | 157 |
|
| 158 | +```java |
| 159 | +class Base { |
| 160 | + @Override |
| 161 | + protected Object clone() throw CloneNotSupportedException { |
| 162 | + //这种情况下会抛出CloneNotSupportedException,因为调用的是Object.clone()方法 |
| 163 | + //return super.clone(); |
| 164 | + return new Base(); //这种方式可不实现Cloneable接口 |
| 165 | + } |
| 166 | +} |
| 167 | +``` |
135 | 168 |
|
0 commit comments