本系列博客皆为读书笔记。读者可看原书<<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技术,特别是关注如何动态地创建和销毁对象。QML是Qt框架提供的一种强大的声明式编程语言,它允许我们构建具有丰富用户界面的应用程序。Qt6版本带来了许多改进和新特性,使得QML...
“对象和内存”涉及到C#的垃圾回收机制。当对象不再被引用时,系统会自动回收其占用的内存。然而,对于处理非托管资源(如文件句柄或数据库连接)的对象,应使用`using`语句或实现`IDisposable`接口来确保资源的正确...
在Java编程中,创建和销毁对象是至关重要的操作,它们直接影响到程序的性能和内存管理。本文将深入探讨Java中创建对象的几种方法以及对象的销毁。 首先,我们来看看创建对象的基本方式——构造器。构造器是每个类都...
本次工程的目标是学习监听器,掌握监听三个对象的创建和销毁方法。 三个对象:rquest,session,ServletContext 实现的接口:ServletRequestListener,HttpSessionListener,ServletContextListener 工程的大致步骤...
"不销毁对象的处理"这个话题涉及到如何在游戏运行过程中保持某些对象的状态,而不是在不再需要时销毁它们,然后在需要时重新创建。这通常用于实现持久化数据、避免频繁的实例化和销毁开销,或者维护一些全局的游戏...
本项目是一个基于Java的对象池管理系统,旨在通过对象池技术减少频繁创建和销毁对象所带来的开销,从而提高系统性能和资源利用率。对象池技术允许在需要时从池中获取已存在的对象,而不是每次都创建新对象,使用完毕...
游戏开发中的对象池技术是一种优化资源管理的策略,它通过预先创建并缓存一组对象,以避免频繁地创建和销毁对象带来的性能开销。在这个"游戏对象池例子(兼容智能指针、工厂类)"中,我们将探讨如何利用C++实现这种...
如果频繁地创建和销毁这些子弹,会消耗大量的内存和CPU资源,因为创建和销毁对象的过程是相对昂贵的。对象池的出现就是为了解决这个问题。 对象池的基本思想是预先创建一组对象,并将它们存储在一个集合中,当需要...
JavaScript是一种动态类型的编程语言,广泛应用于Web开发,其在处理大量临时对象时,可能会因为频繁创建和销毁对象而导致性能下降。为了解决这个问题,开发者们引入了“对象池”概念, DeePool 就是一个实现这一概念...
对象池的基本思想是通过减少频繁地创建和销毁对象来提升性能。当程序需要对象时,它会从池中获取一个已经初始化好的对象,而不是调用构造函数创建新的。使用完毕后,对象不是被销毁,而是返回到池中,供后续使用。...
这种方式可以减少频繁创建和销毁对象带来的性能开销,尤其是在处理大量短生命周期对象的场景下。本文将深入探讨如何使用Dictionary来实现一个简单的对象池,并分析其工作原理、优缺点以及适用场景。 首先,我们来...
这样可以避免因频繁创建和销毁对象带来的性能损失。 在C#中实现自定义对象池,首先需要定义一个类来存储和管理这些对象。这个类通常包含一个队列或字典来保存对象,以及一些方法如获取对象、归还对象等。以下是一个...
1. **减少GC压力**:避免频繁创建和销毁对象,减少垃圾收集器的工作量,提高游戏运行效率。 2. **提高性能**:通过复用对象,减少实例化和销毁的时间开销。 3. **资源管理**:更好地控制对象的生命周期,避免因瞬间...
在编程领域,对象池是一种设计模式,用于管理对象的创建和销毁,以提高程序性能,尤其是在频繁创建和销毁对象的场景下。本文将详细讲解如何使用C#语言实现一个通用的对象池,以及它背后的原理和优势。 首先,理解...
1. **减少创建与销毁开销**:频繁地创建和销毁对象会导致大量的CPU时间消耗在内存分配和垃圾回收上,而对象池能够有效减少这种开销。 2. **节省内存资源**:对象池限制了对象的最大数量,避免了大量临时对象占用内存...
对象池是一种优化资源管理的技术,特别是在频繁创建和销毁对象的场景下。本篇将深入探讨对象池的概念、工作原理以及如何在C++中实现对象池。 对象池的基本思想是预先创建并维护一组对象,而不是每当需要时就动态地...
"对象池"是一种常见的性能优化策略,它针对的是频繁创建和销毁对象所导致的性能损失。本文将深入探讨对象池的概念、工作原理以及在实际应用中的优势和注意事项。 对象池的基本思想是预先创建并维护一组对象,而不是...
它通过预先创建并维护一组可重用的对象,避免了频繁地创建和销毁对象带来的性能开销。本篇将详细介绍对象池的设计原理、常见实现方式以及如何在实际项目中应用。 一、对象池设计原理 1. **内存管理优化**:在Java...