每天看点Effective Java,挺好的,至今觉着Java小菜,多学基础知识,喜欢因为做喜欢的事忘记时间的感觉。
不多吐槽了。直奔主题,这里只是笔记和一些感触,选取了一些我熟悉的类和方法举个例子,因为很久了做Android比较多,我可能会选择一些Android的类库说明android相关的设计理念,对于常用到的就不再举例,一时想不到有些,也不必要非要找出实例,自己做时候注意就好了。如果细致了解建议看原文,原文中提到了一些例子,除了很重要的、以前忽略的这里都不再重复。
一:考虑静态工厂方法代替构造器
->静态工厂方法,不全同设计模式中的工厂模式。
->静态工厂方法可以解决构造函数只能参数类型顺序不同的问题,比如可以两组相同的序列可以用方法名表示不同的含义。
->可以返回子类型,类似工厂模式了。到这里可以屏蔽子类,如针对不同参数返回不同子类优化性能,如果后来发展无法满足需求了,大可增加或删除子类,而构造方法不行。
->对于编码阶段禁忌第一反应是构造方法。
->静态工厂方法缺点,无可继承构造方法时无法子类化,还有在java doc中和其他方法没有区别,而构造方法会单独列出。
二:遇到多个构造器参数时考虑用构造器
->构建器builder。这里很有代表性的就是Android中Dialog的Builder,详见API,提供了先传入参数后构造Dialog的方法。
->多个参数的解决方案中:
重叠构造器包含了用户不期望的默认值。Java bean非线程安全,可能处于不一致状态,且阻止了把类做成不可变的可能。
->构建器使用抽象工厂解决了两者,且可以在对象域(解释下,产生对象的方法)进行约束检查,违反抛出illegalstateexception,或在每个setter进行。
->Java中传统的抽象工厂实现是Class对象,用newInstance方法充当build方法的一部分,这种用法隐含着许多问题。因为newInstance方法总是企图调用类的无参数构造器,这个构造器甚至可能根本不存在。如果类没有可以访问的无参构造器不会出现编译错误,但是client code中必须catchInstantiationException or IllegalAccessException和一切因无参数构造器带来的问题,即使无throws子句。Class newInstantce破坏了编译时的异常检查,而Builder可以弥补。
->缺点:需要多建立一个构造器,代码显得冗长,一般用于多余4个参数调用,但如果你将来有添加参数的可能,那么请用构造器,因为同时存在这些就比较不协调了,对于API的设计来讲是非常不合理的。
三:用私有构造器或枚举类型强化Singleton属性
Singleton属性一般采取的两种方式:
1. 静态final instance
2. 私有final instance,提供静态getInstance方法返回,我们一般采取这种方式,因为它可以保证在API不便的情况下选定是否为Singleton或修改为其他形式。
这里提到这两种方式主要要说明两个没注意的问题:反射和序列化
->反射:这种方式反射都可以访问到构造方法,可以对构造方法做修改,当产生第二个实例抛出异常。
->序列化:仅仅普通方法实现接口是不够的,以为为了保证Singleton,必须要声明所有实例域都是瞬时的,并提供一个readResolve方法。否则存在的问题是每次反序列化一个序列化实例,都会创建一个新的实例。
private Object readResolve(){
return instance;
}
书中提到了1.5增加枚举后的第三种方法,
public enum Elvis{
INSTANCE;
methods......
}
此方法直接解决以上两个问题。Android很重要的就是工具库编写的DB工具类使用了Singleton生成Android自身的dbhandler来处理,虽然不序列化,但是反射是个很严重的问题,毕竟是工具包,所以快点重构吧亲。同样,也许你在HttpHandler中也需要用到。如果没有制作这两个包,建议使用,因为可重用性非常高,也需要解决很多问题,几乎每个项目都使用,同样,保证包的使用的稳定性,不多说了,下一条。
四:通过私有构造器强化不可实例化的能力
->对只有静态方法和域的类,主要用于把基本类型的值或数据类型上的相关方法组织起来(Math,Arrays),可以通过Collections的方法把实现特定接口的对象上的惊天方法组织起来,可以利用这种类把final类上的方法组织起来,以取代扩展该类的做法。
->此工具类是不希望被实例化的,实例化对他么有任何意义。然后我们如果不提供构造器,jvm会自己提供,那还是会被实例化,那么我们只要在类中提供一个私有的构造器就可以了,并添加注释说明。
这样带来的问题是不能子类化,因为子类要求要求super父类的构造函数。
五:避免创建不必要的对象
->若一个方法频繁调用且每次生成相同的内部实例,可以作为static,如Map的keyset。
->维护自己的对象池来避免重复创建对象不是很好的做法,除非对象是非常重量级的,Object pool也增加了内存占用。
六:消除过期的对象引用
存在过期引用会导致无法GC,但清空对象引用应该是一种例外,而不是一种规范行为。
一下三种情况要考虑会发生内存泄露:
1.类自己申请内存管理
2.缓存,易忘记管理,如WeakHashMap可以自动处理没有被外部引用的缓存项。一般利用后台线程定时清理,也可以类似LinkedHashMap使用removeEldestEntry在添加条目时清理。对于复杂的缓存,必须直接使用java.lang.ref
3.监听器和其他回调,回调此时可以做成弱引用。
七:避免使用终结方法
这里先说一下finalize的执行方式,再来说effective java中学到的东西。JVM采用跟搜索算法进行GC对象选择,这里不细说,JVM发现需要回收的对象(当然直观的来看就是没有引用的对象了)会做一次标记并进行一次筛选,筛选的条件就是此对象是否要执行finalize方法(对象未覆盖或finalize已被JVM执行过一次都被视为不需要执行),需要执行的放在F-Queue中,并稍后由一条由虚拟机自动建立的、低优先级的Finalizer线程去执行,但执行仅指虚拟机会触发这个方法,但不承诺会等待此方法运行结束,原因很简单,不可能因为等待这一个进程而使得其他要回收的资源一直等待,这样会导致GCC崩溃。当然一般也没有人会去这样做,毕竟教材没有这样教的,这里effective java中提到了两个用途很重要去掌握,回收资源一般作为一种显示的stop方法。finalize方法的作用:
1. 当用户没有调用stop,这时候在finilize中回收资源总比不回收强,相当于补充一个安全网。(Android中最典型的是MediaPlayer,如果不回收资源将会带来很大的问题,可以查看Android确实是这样做的,它调用的方法如下:
protected void finalize() { native_finalize(); }
具体含义不是这里应该继续讨论的问题,但是需要关注的是如果去做,这里MediaPlayer做的不是realse一样的内容,实际需要考虑finalize执行的问题,它不能耗时太长且不保证执行)
2. 普通对象通过本地方法委托给一个本地对象(本地对等体),因为本地对等体不是普通对象,gC不知道它,当本地对等体不拥有关键资源时finilize是最合适的工具。
需要注意的是,子类如果不super父类的finalize那么不会执行父类的代码,为了防止子类恶意不调可以使用放入一个匿名类,创建一个终结方法守卫者,即当他finalize时会释放外面的资源,与子类调用与否无关。但是此方法不推荐使用,因为方法的本意只是为了让c++程序员更快习惯java的编码而做的妥协,并不是java的析构函数
分享到:
相关推荐
"Effective Java读书笔记" Effective Java是一本关于Java编程语言的经典书籍,本笔记主要总结了Java语言的发展历程、静态工厂方法的应用、构造器模式的使用等重要知识点。 一、Java语言的发展历程 Java语言的发展...
1. **产生和销毁对象** - Item1:静态工厂方法相比构造子,提供了更大的灵活性,例如可以返回对象的子类实例,或者在不改变API的情况下更改返回的对象类型。 - Item2:Builder模式适用于有大量构建参数的情况,它...
读书笔记:Effective Java中文版第3版笔记
### 第二章 创建和销毁对象 这一章深入探讨了对象的生命周期管理,包括: 1. **静态工厂方法**:相比构造器,静态工厂方法有优点如可以不返回新实例、允许返回同一实例(单例)、可以有更具选择性的访问控制,并且...
在 Java 中,创建和销毁对象是非常重要的。静态工厂方法可以代替构造器,提供了更多的灵活性和性能优势。静态工厂方法可以返回原类型的任何子类型,且可以将构建好的实例缓存起来,方便重复利用,不用每次调用都创建...
读书笔记:Effective Java中文版 第2版
Effective Java 读书笔记 - 枚举与注解 本文总结了Effective Java 中关于枚举与注解的知识点,涵盖了枚举类型的优点、使用指南、避免使用 int 常量、使用 EnumSet 和 EnumMap 等。 枚举类型的优点 枚举类型提供了...
总的来说,《Effective Enterprise Java》中文版是一本值得每一个Java开发者阅读的书籍,它不仅提供了丰富的编程技巧,还强调了代码的可读性和可维护性,对于提升个人技能和团队开发效率都有极大的帮助。通过深入...
创建和销毁对象1. 使用静态工厂方法代替构造函数2. 当面对许多构造函数时使用BUILDERS3. 使用私有构造函数或枚举类型强制执行单例属性4. 使用私有构造函数来强制实现不可实例化5. 避免创建对象6. 消除过时的对象...
《Effective Java》是Java开发领域的经典著作,由Joshua Bloch编写,旨在提供一系列实用的编程准则和最佳实践。这本书的第三版包含了大量更新,涵盖了Java语言和平台的新发展,如Java 8和Java 9的新特性。以下是对...
总结来说,静态工厂方法在Java中提供了一种比构造方法更加灵活和高效的方式来创建对象实例,特别是在需要实例控制、性能优化或API设计简洁时。文档《effective-java.pdf》详细地探讨了静态工厂方法在设计和实现上的...
ENCprime中文使用指南:分析序列信息、可计算GC%、Nc ——the effective number of codons[密码子的有效数量]、Ncp ——the effective number of codons prime、ScaledChi 、SumChi 、df —— the corresponding ...
7. **Web服务与SOA**:讨论了Java EE中的Web服务技术,如SOAP和RESTful API的创建,以及面向服务架构(SOA)的设计原则。 8. **持久化框架**:书中介绍了如何使用JPA、Hibernate等持久化框架进行数据库操作,减少...
《Effective Java》是Java...以上仅是《Effective Java》一书中部分核心知识点的概述,实际的读书笔记中会更详细地解释这些概念,并给出具体的示例代码。通过深入学习和实践,开发者可以极大地提升其Java编程的水平。
读书笔记:Effective Java中文版学习项目
### Effective Java读书笔记(上) #### 第一章 引言 本书主要针对Java开发者提供了大量实用的编程指导建议,帮助读者提升代码质量和程序性能。在本章节中,我们将重点介绍对象的创建与销毁,以及一些重要的设计...
读书笔记:Effective.Java中文版(第3版)
根据给定的文件信息,以下是对“精版Effective STL读书笔记”的详细解析,重点提炼了STL(标准模板库)中的关键知识点。 ### 标题:“精版Effective STL读书笔记” 此标题暗示了文档是针对《Effective STL》一书的...