[size=x-large]最近看了一本书,《Effective Java》中文版,内容非常好,但作者有些地方没有讲的太明白,
例子也举的不是很丰富,或许是我水平太低吧,第一次读完感觉云里雾里的。那我反复看了好几次,终于有点头绪。我把自己看过的和自己的
理解记下来分享出来,一是加深一下自己的记忆、整理一下自己的思路;二是大家一块学习,如果有什么不对的地方请大家指点纠正。有些我不是很明白的地方会写出来希望能够得到大家的解答。
书中给总结了78点,今天先写第一点:
考虑用静态工厂方法代替构造器。
在Java中,我们提供实例最常用的方法就是提供一个公有的构造器。那还有一种方法:在类中提供一个共有的静态工厂方法(static factory method),它只是一个返回类的实例的
静态方法。(注:这里说的静态工厂方法和
设计模式中讲的不是一回事)。
一个简单的例子:
class="java">
public static Boolean valueOf(Boolean b){
Return b?Boolean.TRUE:Boolean.FALSE;
}
当你看到这时候会问为什么要用这种方法?有什么好处呢?
书中给总结了几点,我直接抄下来。
第一:静态工厂方法与构造器不同的第一大优势在于,它们有名称。
怎么理解这点呢?那举个例子:构造器BigInteger(int,int,Random) 返回的BigInteger可能为素数,如果用BigIneger.probablePrime的静态工厂方法就很清楚了。建议大家查看BigIneger的源码,对你的理解很有帮助。
在一个类中我们有时候会写好几个构造器,只不过它们的参数个数、参数类型、参数顺序有所不同。我们也会经常调用这样的API,你肯定也纠结过到底用哪个好呢?常常会调用了
错误的构造器。如果这些构造器的代码还没有文档和
注解时你会有想掐死写这个API的作者冲动。
由于静态工厂方法有名称,所以就不会有上面的麻烦了。当然在你使用这样的方法时要非常慎重的选择名称以便突出它们之间的区别,方便客户端的调用。
第二:静态工厂方法不必在每次调用它们的时候都创建一个新的对象。
这点主要是针对不可变类来讲的,可以使用预先构建好的实例或者将构建好的实例缓存起来重复利用,从而避免创建不必要的重复对象。例如:Boolean.valueOf(boolean b)方法。如果经常请求创建相同的对象,但是
创建对象的代价很高,那这项技术可以极大的提升性能。
第三:静态工厂方法可以返回原返回类型的任何子类型的对象。(这一点我不是很明白,求解!!!!)
第四:静态工厂方法在创建参数化实例的时候,它们使代码变得更加简洁。
直接上代码说明:
Map<String,List<String>> map=new HashMap<String,List<String>>();
这段代码应该好多人都用过,有没有觉的很麻烦,而且看的也不爽。
如果HashMap中有下面的方法:
public static <k,v>hashMap<k,v> newInstance(){
return new HashMap<k,v>();
}
那我们调用的时候
Map<String,List<String>> map = HashMap.newInstance();
是不是很简洁呢?
当然静态工厂方法也有它的缺点:
静态工厂方法的主要缺点在于,类如果不包含共有的或者受保护的构造器,就不能被子类化。
静态工厂方法的第二个缺点在于,它们与其他的静态方法实际上没有任何区别。在API文档中没有像构造器那样明确的标识出来,所以对于只提供静态工厂方法而没有构造器的类来说,要想查明如何实例化一个类是很困难的。
不过书中给出的建议:我们在使用静态工厂方法时可以通过规范化命名来弥补这一劣势。下面是惯用的名称:
valueOf
of
getInstance
newInstance
getType
newType。
第一次写这么长的博客,有什么意见或建议大家提出来,今天就先写到这。[/size]