Effective Java 学习笔记(一)

本文探讨了使用静态工厂方法替代构造器的优缺点。优点包括:命名独特、避免不必要的对象创建、返回任意子类对象、灵活性高以及在服务提供者框架中的应用。缺点主要在于不易发现和不可继承。举例说明了静态工厂方法在如`Boolean.valueOf()`等方法中的应用,以及其如何在`BigInteger`和`EnumSet`等类中提高效率和灵活性。
摘要由CSDN通过智能技术生成

条款1:考虑使用静态工厂方法替代构造器

客户端获得实例的传统方式是使用public构造器,还有另一种方式——静态工厂方法(与设计模式中的没啥关系哈)。

下面是一个例子,boolean装箱成Boolean:

public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

采用静态工厂方法的优点:

1. 每个方法有独特的名字。例如:BigInteger(int, int, Random)构造器返回一个可能是素数的BigInteger,用静态工厂方法就可以起这么个名字:BigInteger.probablePrime。而类的构造器只能以类名命名,仅通过参数列表是很难得知构造器具体作用,必须要阅读文档才行。因此,将构造器替换为静态工厂方法可以用不同的名字来区分类的多个构造器

2. 不需要在每次调用的时候都创建一个新对象。静态工厂方法可以让不可变类使用预先创建好的实例;或者缓存并重复使用已创建的实例来避免创建多余的对象。例如:Boolean.valueof(boolean)方法永不创建对象,只返回已创建好的TRUE或FALSE。静态工厂方法可以严格地控制在某时刻哪些实例应该存在,这种类称为实例受控的类。实例控制可以实现单例类或者不可实例化类。

3. 可以返回任何返回值类型的子类对象。截止到Java 8,接口中不能包含静态方法。一种可行的方法是把名为Type的接口的静态工厂方法放到一个不可实例化的工具类Types中。例如,java.util.Collection接口有45个实现类,而几乎所有的实现类都能从java.util.Collections类中获取。这样做能减少对API概念的掌握,返回的对象是被API精确指定的,就不用去读各种文档了。

4. 返回的对象对应的类可以在调用时根据输入参数值而变化。只要是返回值类型的子类都可以,。例如,EnumSet类的静态工厂方法会根据参数返回两种子类中的一种实例:如果枚举类型的元素不超过64,则返回RegularEnumSet实例,采用一个long变量支持;超过则返回JumboEnumSet实例,用一个long数组支持。这种返回方式客户端是不知道的。未来也可以根据性能再添加第三个、第四个EnumSet子类,而用户只需要使用获得的实例,不需要关心实例是怎么来的。

5. 当某个类编写静态工厂方法时,静态工厂方法返回的对象对应的类可以不必存在。这种静态工厂方法是服务提供者框架的基础,JDBC就应用了这个东东。


缺点:

1. 只含private、package-private构造器的类无法被继承。不过这也反向鼓励了程序猿们多用组合少用继承了。

2. 静态工厂方法不容易被找到。由于不像构造器那么显眼,它们可能混在一堆API中很难被发现。以下是一些常用命名:

from——类型转换,将传入的参数转换成本类对应的实例。

of——把一堆参数合并到一起,返回合并后本类对应的实例。

valueOf——跟from和of差不多,名字长点。

instance或getInstance——根据传入参数获取实例(如果有的话),但也不一定有相同的值。

create或newInstance——除了这个要返回一个新的实例以外和上面的那个一样的。

getType——跟getInstance差不多,如果获取不同类型的实例的话,就用实际的Type来替代Instance,达到区分。

newType——跟newInstance差不多,如果获取不同类型的实例的话,就用实际的Type来替代Instance,达到区分。

type——简化版getType和newType。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值