第2条:遇到多个构造器参数时要考虑用构建器

与构造器相比,builder的微略优势在于,builder可以有多个可变(varargs)参数。构造器就像方法一样,只能有一个可变参数。因为builder利用单独的方法来设置每个参数,你想要多少个可变参数,它们就可以有多少个,直到每个setter方法都有一个可变参数。

第6条:消除过期对象引用

一般而言,只要类是自己管理内存,程序员就应该警惕内存泄漏问题。一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空。

内存泄漏的另一个常见来源是缓存。一旦你把对象引用放到缓存中,它就很容易被遗忘掉,从而使得它不再有用之后很长一段时间内仍然留在缓存中。对干这个问题,有几种可能的解决方案。如果你正好要实现这样的缓存:只要在缓存之外存在对某个项的键的引用,该项就有意义,那么就可以用WeakHashMap代表缓存,当缓存中的项过期之后,它们就会自动被删除。记住只有当所要的缓存项的生命周期是由该键的外部引用而不是由值决定时,WeakHashMap才有用处。

内存泄漏的第三个常见来源是监听器和其他回调。如果你实现了一个API, 客户端在这个API中注册回调,却没有显式地取消注册,那么除非你采取某些动作,否则它们就会积聚。确保回调立即被当作垃圾问收的最佳方法是只保存它们的弱引用(weak reference。例如,只将它们保存成WeakHashMap中的键。

第7条:避免使用终结方法

注重时间(time-critical)的任务不应该由终结方法来完成。例如,用终结方法来关闭已经打开的文件,这是严重错误,因为打开文件的描述符是一种很有限的资源。

不应该依赖终结方法来更新重要的持久状态。例如,依赖终结方法来释放共享资源(比如数据库)上的永久锁,很容易让整个分布式系统垮掉。

还有点:使用终结方法有一个非常严重的(Severe)性能损失。

那么,如果类的对象中封装的资源(例如文件或者线程)确实需要终止。应该怎么做才能不用编写终结方法呢?只需提供一个显式的终止方法,并要求该类的客户端在每个实例不再有用的时候调用这个方法。

显式的终止方法通常与try-finally结构结合起来使用,以确保及时终止。在finally子句内部调用显式的终止方法,可以保证即使在使用对象的时候有异常抛出,该终止方法也会执行:

那么终结方法有什么好处呢?’它们有两种合法用途。第一种用途是,当对象的所有者忘记调用前面段落中建议的显式终止方法时,终结方法可以充当“安全网(safety net ) "。虽然这样做并不能保证终结方法会被及时地调用,但是在客户端无法通过调用显式的终止方法来正常结束操作的情况下(希望这种情形尽可能地少发生),迟一点释放关键资源总比永远不释放要好。但是如果终结方法发现资源还未被终止,则应该在日志中记录一条警告,因为这表示客户端代码中的一个bug,应该得到修复。

值得注意的很重要一点是,“终结方法链(Finalizer chaining)”并不会被自动执行。如果类(不是Object)有终结方法,并且子类覆盖了终结方法,子类的终结方法就必须手工调用超类的终结方法。你应该在一个try块中终结子类,并在相应的finally块中调用超类的终结方法。

《Effective Java》第2章 创建和销毁对象的更多相关文章

  1. [Effective Java 读书笔记] 第二章 创建和销毁对象 第一条

    第二章  创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法 ...

  2. [Effective Java读书笔记] 第二章 创建和销毁对象(1~7)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537576.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  3. 《Effective Java》第1章 创建和销毁对象

    第1条 用静态工厂方法代替构造器 这个静态工厂,与设计模式中的静态工厂不同,这里的静态工厂方法,替换为“静态方法”比较好理解,主要就是建议编写静态方法来创建对象. 使用静态方法的好处: 1.静态方法有 ...

  4. [Effective Java 读书笔记] 第二章 创建和销毁对象 第六-七条

    第六条 消除过期引用 JAVA中依然会有 memory leak的,比如一个栈先增长再收缩,那么从栈中弹出的对象是不会被当做垃圾回收的,即时使用栈的程序不再引用这些对象.这是因为栈的内部维护着对这些对 ...

  5. [Effective Java 读书笔记] 第二章 创建和销毁对象 第五条

    第五条 避免创建不必要的对象 书中一开始举例: String s = new String("stringette"); // don't do this //应该使用下面,只会创 ...

  6. [Effective Java 读书笔记] 第二章 创建和销毁对象 第三 四条

    第三条 用私有构造器或者枚举类型强化singleton属性 singleton指只能被实例化一次的类,即将构造器设置为私有,使用公有静态成员来实例化,且只实例化一次对象 第四条 通过私有构造器强化不可 ...

  7. [Effective Java 读书笔记] 第二章 创建和销毁对象 第二条

    第二条 遇到多个构造器参数时,可以考虑用构建器 当遇到有多个构造器参数时,常见的是用重叠构造器,即: public class TestClass{ public TestClass(int para ...

  8. 《Effective Java》读书笔记 - 2.创建和销毁对象

    Chapter 2 Creating and Destroying Objects item 1:Consider static factory methods instead of construc ...

  9. 《Effective Java 2nd》第2章 创建和销毁对象

    目录 第1条:考虑使用静态工厂方法代替构造器 第2条:遇到多个构造器参数时考虑用构建器 第3条:用私有构造器或者枚举类型强化Singleton属性 第4条:通过私有构造器强化不可实例化的能力 第5条: ...

随机推荐

  1. THUPC2017 小 L 的计算题

    求 $k=1,2,\cdots,n \space \space \sum\limits_{i=1}^n a_i^k$ $n \leq 2 \times 10^5$ sol: 时隔多年终于卡过去了 之前 ...

  2. C#异步编程(四)混合模式线程同步

    之前讨论了基元用户模式和内核模式线程同步构造.其他所有线程同步构造都基于它们,而且一般都合并了用户模式和内核模式构造,我们称为混合线程同步构造.没有线程竞争时,混合构造提供了基元用户模式构造所具有的性 ...

  3. [Luogu3727]曼哈顿计划E

    luogu 题意(简化版) 给你一棵树,每个点上有一个\(SG\)值,问你是否存在一条路径使得\(SG\)异或和为\(0\). sol 可以当做每个点的稳定值就是这个点上的石子数量. 很显然我们只需要 ...

  4. [Wc2009]shortest

    传送门 终于把这题过了,了了我两年前写堵塞的交通一晚上无果的心结 因为是6要注意蛇皮走位啊!!这种-> S //Achen #include<bits/stdc++.h> #defi ...

  5. 消息队列mq总结(重点看,比较了主流消息队列框架)

    转自:http://blog.csdn.net/konglongaa/article/details/52208273 http://blog.csdn.net/oMaverick1/article/ ...

  6. 在装有windows跟ubuntu的机器上重新安装windows后修复ubuntu的grub

    本文只对没有单独用类似easyBCD这种软件单独设立启动分区的双系统,在重新安装win7之后,因为win7覆盖了ubuntu的grub,导致ubuntu无法启动的问题. (1)不管使用什么方法,首先需 ...

  7. Java实现Stack类

    Java实现Stack类 import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Sc ...

  8. 【转】hurry_liu 大神STM32移植contiki入门之一:系统介绍和开发环境搭建

    前言: 由于项目的原因,需要在LPC1788(STM32 cortex-M3)上面跑contiki. 之前没有涉及到contiki,不知其为何物.不过这个不是难事,做IT的,每每遇到新事物,都不会处理 ...

  9. Servlet3.0之八:基于Servlet3.0的文件上传@MultipartConfig

    在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件,在Servlet3.0中提供了对文件上传的原生支持,我们不 ...

  10. 组装恢复rbd

    标签: ceph,ceph实验,rbd cluster相关环境: # cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) # ce ...