`
逆天子军少
  • 浏览: 77706 次
  • 性别: Icon_minigender_1
  • 来自: 安庆
社区版块
存档分类
最新评论

创建和销毁对象

阅读更多
本系列博客皆为读书笔记。读者可看原书<<Effective Java>>

本篇的主题是创建和销毁对象

第一条:考虑用静态工厂方法代替构造器
为了获取类的一个实例,最常用的方法就是提供一个公有的构造器,但类也可以提供一个公有的静态工厂方法。(这里的静态工厂方法与设计模式中的工厂方法模式不同)
静态工厂方法与构造器相比有下面几个优势:
1.静态工厂方法有名称
具有适当名称的静态工厂将更容易使用和阅读。
2.不必在每次调用静态工厂方法的时候都创建一个新对象
这个优势使得不可变类可以使用预先构件好的实例,或者将构架好的实例缓存起来,进行重复利用,从而避免创建不必要的重复对象。
3.返回原返回类型的任何子类型的对象
我们在选择返回对象的类时有了很大的灵活性,其中一种应用是,API可以返回对象,同时又不会使对象的类变成共有的。以这种方式隐藏实现类会使API变得非常简洁。这项技术适用于基于接口的框架,在这种框架中,接口为静态工厂方法提供了自然返回类型。
4.在创建参数化类型实例的时候,静态工厂方法使代码变得更加简洁
Map<String , List<String>> m = HashMap.newInstance();

但是静态工厂方法也有缺点:
1.类如果不含公有的或者受保护的构造器,就不能被子类化
2.静态工厂方法与其他的静态方法实际上没有任何区别
不能像构造器那样明确标识,在提供了静态工厂方法而不是构造器的类中,要想查明如何实例化一个类,比较困难。但也还是有些惯用名称:valueof ,of , getInstance , newInstance , getType , newType.

第二条:遇到多个构造器参数时要考虑用Builder模式
静态工厂和构造器有个共同的局限性,都不能很好地扩展到大量的可选参数。可能你喜欢用重叠构造器模式,但参数很多时,代码很难编写,阅读性差。或者你喜欢用JavaBeans模式,这种模式确实弥补了构造器模式的不足,但其自身有着严重的缺点。因为构造过程中被分到了几个调用中,在构造过程中JavaBean可能处于不一致的状态。而且,JavaBeans模式阻止了把类做成不可变类的可能。
这时,我们有第三种方法,既能保证安全性也能保证可读性,那就是Builder模式。不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或静态工厂方法),得到一个builder对象。然后客户端在builder对象上调用类似setter方法,设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员类。

第三条:用私有构造器或者枚举类型强化Singleton属性
Singleton是指仅仅被实例化一次的类。在java 1.5发行之前,实现Singleton有两种方法。这两种方法都要把构造器保持为私有,并导出公有的静态成员。这个静态成员可以是final域或者是静态方法。从java 1.5发行起,实现Singleton还有第三种方法,只需编写一个包含单个元素的枚举类型:
public enum Elvis{
  INSTANCE;

 public void method(){...}
}

这种方法已经成为实现Singletong的最佳方法,更加简洁,并无偿提供了序列化机制,绝对防止多次实例化,即使是面对复杂的序列化或者反射攻击。

第四条:通过私有构造器强化不可实例化的能力
企图通过将类做成抽象类来强制该类不能被实例化,是行不通的。该类可以被子类化,该子类可以被实例化。我们可以让这个类包含私有构造器,她就不能被实例化了。但在这种情形下,子类就没有可访问的超类构造器可调用了。

第五条:避免创建不必要的对象
并不意味着创建对象的代价非常昂贵。相反,由于小对象的构造器只做很少量的显式工作,所以,小对象的创建和回收是非常廉价的。

第六条:消除过期的对象引用
java因为支持垃圾回收,所有有些情况下内存泄露是很隐蔽的。如果一个对象引用被无意识的保留起来了,那么,垃圾回收机制不仅不会处理这个对象,而且也不会处理被这个对象所引用的所有其他对象。
这类问题的修复方法很简单:一旦对象引用已经过期,只需清空这些引用即可。一般而言,只要类是自己管理内存(比如Stack),程序员就应该警惕内存泄露。一旦元素被释放掉,该元素中包含的任何对象就应该被清空。内存泄露的另一个常见来源是缓存。缓存应该时不时清除掉无用的项,这项清除工作可以由一个后台线程完成,或者也可以在给缓存添加新条目时顺便进行清理。LinkedHashMap可以很容易实现后一种方案。对于更加复杂的缓存,直接使用java.lang.ref。内存泄露的第三个来源是监听器和其他回调。确保回调立即被当做垃圾回收的最佳方法是只保存他们的弱引用。

第七条:避免使用终结方法
终结方法(finalizer)通常是不可预测的,也是很危险的。其缺点在于不能保证会被及时执行,甚至不能保证会不会执行。我们可以提供一个显示的终止方法代替编写终结方法。通常,终止方法与try-finally结合使用,确保及时终止。
终结方法有两种合法用途,充当“安全网”或者终止非关键的本地资源。即使使用了终结方法,也要记住调用super.finalize.如果用来充当安全网,要记得记录终结方法的非法用法。最后,如果需要把终结方法与公有的非final类关联起来,请考虑使用终结方法守卫者,确保即使子类的终结方法未能调用super.finalize,该终结方法也能被执行。


分享到:
评论

相关推荐

    Qt6 QML Book/动态QML/创建和销毁对象示例源码

    Qt6 QML Book/动态QML/创建和销毁对象 示例源码 CSDN审核可能较慢,如无法下载,可以过段时间再回来看下 仅供相关爱好者交流使用,请于下载24小时内删除

    C#创建、销毁对象和继承

    内容提要 • 使用构造方法 • 初始化数据 • 对象和内存 • 资源管理 派生类 • 实现方法 • Sealed类 • 使用接口 • 使用抽象类

    JAVA创建和销毁对象的方法

    本篇文章主要介绍了JAVA创建和销毁对象的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    监听器:监听三个对象的创建和销毁方法

    本次工程的目标是学习监听器,掌握监听三个对象的创建和销毁方法。 三个对象:rquest,session,ServletContext 实现的接口:ServletRequestListener,HttpSessionListener,ServletContextListener 工程的大致步骤...

    Java线程池技术详解

    在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一...

    c++多线程的创建挂起执行与销毁

    1. 创建一个基于对话框的应用程序。并增加如图所示控件;分别为3个进度条控件关联...//销毁线程句柄 } else { MessageBox("终止进程失败!"); } 11. 为应用程序添加WM_TIMER消息,实时更新全局变量的值到编辑框;

    C++ 编程思想(PDF)

    1.7 创建和销毁对象 11 1.8 异常处理:应对错误 12 1.9 分析和设计 12 1.9.1 第0阶段:制定计划 14 1.9.1.1 任务陈述 14 1.9.2 第1阶段:我们在做什么 14 1.9.3 第2阶段:我们将如何建立对象 16 1.9.3.1 对象...

    C++动态内存分配(new/new[]和delete/delete[])详解

    为了解决这个普通的编程问题,在运行时能创建和销毁对象是基本的要求。当然,C已提供了动态内存分配函数malloc( )和free( ),以及malloc( )的变种(realloc:改变分配内存的大小,calloc:指针指向内存前初始化),这些...

    ACE对象生命周期管理者:一种用于控制对象创建和销毁的补充模式

    目的对象生命周期管理者模式可以被用来控制对象的整个生命周期,从对象被首次使用前创建它们到应用程序中止前完全的销毁它们。此外通过在应用启动/中止时进行对象自动的预先创建/销毁,使这个模式能够用来替代静态...

    监听session的创建到销毁

    这是一个用springMVC的项目 是一个监听器 用于监听session的创建、销毁、移除。会触发相应的事件处理

    从使用到原理学习Java线程池

    在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个...

    用Python实现一个简单的线程池

    在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一...

    java高效编程指南

    JAVA高效编程指南 1 创建和销毁对象 2 对象定义 3 类和接口 4 结构的替代

    课堂笔记_c++应用1

    1.3 线程池面向对象编程中,创建和销毁对象是很费时的,因为创建一个对象要获取内存资源或者其它更多资源 2.2 IO复用机制2.2.1 select#inclu

    ThreadPool:Java 线程池的使用 例子

    线程池的技术背景在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高...

    java教学笔记之对象的创建与销毁

    面向对象的编程语言使程序能够直观的反应客观世界的本来面目,并且使软件开发人员能够运用人类认识事物所采用的一般思维方法进行软件开发,是当今计算机领域中软件开发和应用的主流技术。

    java逻辑思维笔试题-effective-java-3rd-edition:有效的Java第3版注释

    创建和销毁对象 03 - 所有对象通用的方法 04 - 类和接口 05 - 泛型 06 - 枚举和注释 07 - Lambda 和流 08 - 方法 09 - 通用编程 10 - 例外 11 - 并发 12 - 序列化 第 2 章 - 创建和销毁对象 第 1 项 - 考虑静态工厂...

    Effective Java第三版1

    《Effective Java》第三版中文版目录 第一章 介绍 1 第二章 创建和销毁对象 4 1 考虑用静态工厂方法替换构造器 4 2 当遇到多个构造器参

Global site tag (gtag.js) - Google Analytics