创建类的实例的最常见方式使用new语句调用类的构造方法。这种情况,程序可以创建类的任意多实例,每执行一条new语句,都会导致java虚拟机在堆区产生一个新的对象。假如类需要进一步封装创建自身实例的细节,并且控制自身实例的数目,那么可以提供静态工厂方法。
如Class实例就是java虚拟机加载一个类时自动创建的,程序无法用new语句创建java.lang.Class类的实例,因为Class类没有提供public类型的构造方法。为了使程序获得代表某个类的Class实例,在Class类中提供了静态工厂方法forName(String name):
Class c=Class.forName("Sample"); //返回代表Sample类的实例
静态工厂方法与用new语句调用的构造方法比较:
(1)构造方法必须与类名相同,缺点类的所有重载的构造方法名称相同,易混淆;静态工厂方法的名字可以是任意的,如下定义了两个Gender类的静态工厂方法getFemale()和getMale():
public class Gender { private String description; private static final Gender female=new Gender("女"); private static final Gender male=new Gender("男"); private Gender(String description){ this.description=description; } //静态工厂方法 public static Gender getFemale(){ return female; } //静态工厂方法 public static Gender getMale(){ return male; } public String getDescription(){ return description; } }
但这样定义用户也难以识别类中哪些静态方法专门负责返回类的实例,所以目前比较流行将静态工厂方法命名为ValueOf或者getInstance。
ValueOf:该方法返回的实例与他的参数具有同样的值:
Integer a=Integer.ValueOf(100); //返回取值为100的Integer对象,ValueOf()方法执行类型转换操作
getInstance:返回的实例与参数匹配
Calender c=Calender.getInstance(Local.CHINA); //返回符合中国标准的日历
(2)每次执行new语句,都会创建一个新的对象。而静态工厂方法每次被调用,是否会创建一个新的对象完全取决于方法的实现。
(3)new语句只能创建当前类的实例,静态工厂方法可以返回当前类子类的实例,这一特性在创建松耦合系统接口时发挥作用。
静态工厂方法主要特点是:每次调用,不一定要创建一个新的对象。利用这一特点,静态工厂方法可创建以下类的实例:
单例类:只有唯一实例的类;
枚举类:实例的数量有限的类;
具有实例缓存的类:能把已经创建的实例暂且存放在缓存中的类;
具有实例缓存的不可变类:不可变类实例一旦创建,其属性值就不会改变。