这个文集,是我读Effective Java的笔记。Udacity的老师说,如果你想养成一个习惯,就要在你每天的schedule里面拿出一段固定的时间留给这件事。深表赞同。下面开始。
这篇是<Effective Java>中的第一条。
什么是static factory method
看看Boolean.java中的一个静态工厂方法:
//类型转换
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
好处
第一个好处:可以自己取名字-->方法名中能体现与实例有关的信息
构造方法可以创建一个对象的instance,静态工厂方法也可以得到一个instance。这里一个显著的区别是,静态工厂方法可以自己取名字。自己取名字有什么好处?很多情况下我们想要创建不同类型的实例,会通过overload(重载)构造函数来达到目的。但缺点是没法判断得到的是什么样的instance,而取名字的话就可以从方法名中能得到与实例有关的信息。
这样做的缺点:用户难以识别类中到底哪些静态方法专门负责返回类的实例。解决方法是采用约定俗成的命名,比如:
- valueOf:该方法返回的实例与它的参数具有同样的值,例如:
Integer a=Integer.valueOf(100); //返回取值为100的Integer对象
- getInstance:返回的实例与参数匹配,例如:
Calendar cal=Calendar.getInstance(Locale.CHINA); //返回中国日历
第二个好处:可以返回不同的类型,比如子类
这个在Collections中用得多。比如创建一个List,可以返回一个ArrayList。
第三个好处:不用每次创建新对象
例如单例模式。还有上面的Boolean的valueOf函数。
第四个好处:简洁
//使用构造器创建
Map<String, List<String>> m1 = new HashMap<String, List<String>>();
//使用静态工厂方法创建
Map<String, List<String>> m2 = HashMap.newInstance();
坏处
- 如果类中没有提供public或protected的构造器,将造成该类不能子类
我的理解:这是因为,如果父类只有private的构造方法,它是没办法被子类继承的。子类的构造方法会自动用super()调用父类的public/protected构造方法,但如果没有public或者protected方法,就没法被继承。
「单例」的新理解
这里我对单例有了更深刻的理解。因为单例就是只有private的构造方法的;这即是说,单例的意义不仅仅在于不创建新的实例,而且在于不返回这个实例的任何子类instance。
private Singleton() {}
(突然想去去年面试网易,人家让我写个单例我都写得磕磕绊绊。。
- 静态工厂方法和其他静态方法本质上并没有区别。