Effective Java--读书笔记
Posted kz2017
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Effective Java--读书笔记相关的知识,希望对你有一定的参考价值。
第2章 创建和销毁对象
1.考虑用静态工厂方法代替构造函数-->静态工厂模式。
2.使用私有构造函数强化singleton属性-->单例模式。
3.通过私有构造函数强化不可实例化的能力:
a.企图通过将一个类做成抽象类来强制该类不可被实例化,是行不通的。
b.只要让该类包含单个显示的私有构造函数,则它就不可被实例化了。
4.避免创建重复的对象。
5.消除过期的对象引用。
6.避免使用finalizer函数。
内存泄漏问题:
如果一个栈显示增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收,即使使用栈的客户程序不再引用这些对象,它们也不会被回收。这是因为,栈内部维护着对这些对象的过期引用。
问题修复:
一旦对象引用过期,就清空这些引用。(比如 当一个单元被弹出栈,就把它的引用设置为null)。这样的好处是,如果它们在以后又被错误地解除引用,则程序会立即抛出空指针异常,而不是悄悄地错误运行下去。
场景:
1.只要一个类自己管理它的内存。
2.缓存。
第3章 对于所有对象都通用的方法
7.在改写equals的时候请遵守通用约定:
当一个类有自己特有的“逻辑相等”概念(而不是它们是否指向同一个对象),而且超类也没有改写equals以实现期望的行为,这时我们需要改写它。
这通常适合于“值类”的情形,比如Integer或者Date。
通用约定:
a.自反性;对于任意的引用值x,x.equals(x)一定为true。
b.对称性;对于任意的引用值x和y,并且仅当y.equals(x)返回true时,x.equals(y)也一定返回true。
c.传递性;对于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也一定返回true。
d.一致性;对于任意的引用值x和y,如果equals比较的对象信息没有被修改的话,那么,多次调用x.equals(y)要么一致地返回true,要么一致地返回false。
e.非空性;对于任意的非空引用值x,x.equals(null)一定返回false。
实现高质量equals方法的一个“处方”:
1.使用==操作符检查“实参是否为指向对象的一个引用”;
2.使用instanceof操作符检查“实参是否为正确的类型”;
3.把实参转换到正确的类型;
4.对于该类中每一个“关键(significant)”域,检查实参中的域与当前对象中对应的域值是否匹配。
5.当你编写完后,检查它是否对称的、传递的、一致的。
8.改写equals时总是要改写hashCode相等的对象必须具有相等的hash码。
9.总是要改写toString。默认返回的是类名[email protected]+16位进制的hash码。
第6章 方法
23.检查参数的有效性-->做校验。
24.需要时使用保护性拷贝:
Java是安全的语言,对缓冲区溢出、数组越界、非法指针以及其他的内存破坏错误自动免疫。
25.谨慎设计方法的原型:
a.遵循标准的命令习惯。
b.不要过于追求提供便利的方法,只有一个操作被用得非常频繁时候,才提供快捷方法。
c.避免长长的参数列表,三个视为实践中的最大值。
d.对于参数类型,优先使用接口而不是类。例如,没有理由在编写一个方法时使用Hashtable作为输入,相反,应该使用Map。这使得你可以传入一个Hashtable、HashMap、TreeMap的子映射表。如果你使用一个类而不是一个接口,则限制了客户只能传入一个特定的实现。
e.谨慎地使用函数对象。
26.谨慎地使用重载:
永远不要导出两个具有相同参数数目的重载方法。
27.返回零长度的数值而不是null。
第7章 通用程序设计
31.如果要求精确的答案,避免使用float和double-->不适合用作货币计算。
33.了解字符串连接的性能:
使用StringBuffer的append方法。
34.通过接口引用对象
尽量这样声明:
List subs=new ArrayList();
而不是这样的声明:
ArrayList subs=new ArrayList();
如果没有合适的接口存在的话,那么,用类来引用一个对象,是合适的。
第8章 异常
40.对于可恢复的条件使用被检查时异常,对于程序错误使用运行时异常。
46.努力使失败保持原子性:
一个失败的方法调用应该使对象保持“它在被调用之前的状态”。
47.不要忽略异常:
catch块也应该包含一条说明,用来解释为什么忽略掉这个异常是合适的。
第9章 线程
51.不要依赖于线程调度器(thread schcduler):
1.任何依赖于线程调度器而达到正确性或性能要求的程序,很有可能是不可移植的。
2.不要企图通过调用Thread.yield来“修正”程序。
3.线程优先级是Java平台上最不可移植的特征。
4.Thread.yield的唯一用途是在测试期间人为地增加一个程序并发性。
53.避免使用线程组。
第10章 序列化
54.谨慎地实现Serializable:
1.实现它的最大代价是,一旦一个类被发布,则“改变这个类的实现”的灵活性将大大降低。
2.第二个代价是,增加了bug和安全漏洞的可能性。
3.第三个代价是,随着一个类的新版本的发行,相关的测试负担增加了。
55.考虑使用自定义的序列化形式。
56.保护性地编写readObject方法。
57.必要时提供一个readResolve方法。
以上是关于Effective Java--读书笔记的主要内容,如果未能解决你的问题,请参考以下文章