Effective Java (第三版) item1-静态工厂方法

Effective Java终于出了第三版,紧跟时代的步伐,新增了对新版本的java的解读.

因为是老外写的,到现在为止只有英文版的,其实吧,这书的pdf版本,我已经拿到有一段时间了.但是没空看,昨天下午花了一点时间,今天上午又花了一点时间把其中的 item1,读完了,是写静态工厂方法的.尝试这翻译了一下(由于英语水平的不过关,其中几个单词不是很理解,大家凑合看看吧).

本书中介绍,作者使用的OpenJDK9.0.0.15 的版本,使用windows 7 professional SP1 (64位)

静态工厂方法代替构造方法

传统的获取一个对象的方法,是使用一个public的构造方法.现在我们有了另外一个技术,获取一个对象,一个类提供一个public static 工厂方法,返回一个类的实例.例如:
public static Boolean vlaueOf(boolean b){
return b?Boolean.TRUE:Boolean:FALSE;
}

一个类实例化可以提供静态工厂方法,也可以使用public的构造方法.他们都有各自的优缺点.




第一个优点:
它不像构造方法一样,他们有名字的.
我们能够给他起一个更直白的名字表达意思.
例如构造方法BigInteger(int,int,Random) 返回一个BigInteger ,当然了使用静态工厂方法更好的表达意思是BigInteger.probalePrime
当出现了多个构造方法的时候,根据构造方法的参数顺序来进行区分是一个坏主意,因为这种API记不住啊.
而工厂方法有名字,而且分别很大,使用工厂方法代替构造方法,可以选择更好的名字来区分

第二个好处:
他不像构造方法,他不需要每次调用的时候就创造一个新的对象.
他们允许不可变的类,使用提前已经构建的示例,或者还款的示例,当做当他们被创建了.避免重复创建多个不需要的对象.
例如:
public static Boolean vlaueOf(boolean b){
return b?Boolean.TRUE:Boolean:FALSE;
}
从来不创建对象.这就极大的改善了如果经常请求,尤其是创建的很消耗资源的时候.

还能够保证:单例,不可变的,


第三个好处:
他们能够返回任意类型,而不是构造方法只能返回自己的类型.

下面说的是以java的集合为例的多态,一个接口的多个不同的实现.所有的synchronize集合在不可实例的Collections类中都可以提供出来.如:静态方法 unmodifiableSet(Set<? extends T> s) 

java8的接口中可以有默认方法了.java8接口需要所有的成员都是public的
java9中允许有private static 方法,但是static 属性和static 成员类依然要是public的


第四个好处:
返回结果可以根据参数进行类型的转换,任何子类型都是有可能的.
EnumSet 类 没有public 构造方法,只有静态工厂方法.在openJDK中,他返回一个子类的实例.如果只有小于64个元素,返回的是RegularEnumSet 实例,是一个long.
当超过64个元素,工厂方法返回是JumboEnumSet 实例,返回的是一个long[] 数组.
这是两个实现,当然了,我们还可以为EnumSet提供第三种实现的方式.


第五个好处:
返回结果不需要存在,当工厂方法写的时候
像JDBC的链接

提供静态工厂方法的主要限制是类没有public 或者protected 的构造方法,不能对子类进行实例化

静态工厂方法另外一个缺点是程序员很难找到他们(因为以前实例化一个类,只需要知道是哪个就行了,现在我们却要知道他的工厂类.).
下面列举了一些常用的静态工厂的方法名字,距离详尽还差很远

一个方法名字示例:
from 一种类型转换方法.单个参数传入,返回一个符合要求的实例.例如:
Date d=Date.from(instant);

of   一个吧多个参数聚合然后返回一个实例的方法.例如:
Set<Rank>  facrCards = EnumSet.of(JACK,QUEEN,KING);

valueOf  一种作为from和of的替代.例如:
BigInteger prime=BigInteger.valueOf(Integer.MAX_VALUE);

instant 或者getInstance   返回一个参数描绘的实例,但不一定是同一个对象,例如:
StackWalker luke=StackWalker.getInstance(options);

create 或者 newInstance 像instance 或getInstance  方法保证每次被调用都返回一个新的对象.例如:
Object newArray =Array.newInstance(classObject,arrayLen);

getType 像getInstance 但是用在当一个工厂方法在一个不同的类中的时候,返回工厂方法,例如:
FileStore  fs=Files.getFileStore(path);

newType  像newInstance  但是用在如果工厂方法在一个不同的类中.返回工厂方法,例如:
BuffferedReader  br=Files.newBufferedReader(path);

type   一个简明的可以代替getType  和  newType,例如:
List<Complaint>  litany= Collection.list(legacyLitany);


总结:静态工厂方法和public 构造方法同时使用.他们都有相应的优点.
当然了作者更加的推荐使用工厂方法,可以避免通过反射来提供public构造方法.

我的理解其实就是为了把对象的创建,和使用分离开,因为我们使用对象作为一种封装数据的数据结构,我们只是把对象当做一种工具使用,真正关心的不是他的创建,而是在他的使用上面.这也是spring流行的原因,就是因为他帮助我们对整个项目中使用到的对象的进行管理,我们需要使用的时候直接进行注入就可以了.

说了这么多.其实也是我上面的写的我的理解.
理解是一回事,但是在实际中使用又是另外一回事了.

好了,今天就写到这里,因为是英文版的看起来也很费力,大家如果需要Effective Java 的第三版的英文版,可以发送邮件 标题为"effective java第三版" 到[email protected] 进行索取(仅学习交流使用).其中难免有错误,请指正,谢谢

还有3天放假,就可以回家看我的小可爱了,哈哈哈.希望小可爱好好复习,能考过教师资格证.


https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-18045781879.2.33c5236bZlPDUM&id=569353717228
深入理解Java虚拟机(jvm性能调优+内存模型+虚拟机原理)   很不错的虚拟机视频教程.


猜你喜欢

转载自blog.csdn.net/u010398771/article/details/79245074