第1条:用静态工厂方法代替构造器

第1条:用静态工厂方法代替构造器

所谓静态工厂方法,实际上只是一个简单的静态方法,它返回的是类的一个实例。

使用静态工厂方法的优点有:

1)它与构造函数不同,它有名字,你可以把名字起的更易于阅读。

如果你想让2个构造函数拥有相同个数和类型的参数,这将是无法实现的;即使是2个不同类型的参数顺序倒置的,使用者也非常容易搞混乱。

例:一个类Complex(复数:包含实部和虚部)对它的构造可能有这样2种需求:

  • 分别给出实数部和虚数部来构造之;
  • 基于极坐标来构造(提供“半径”和“角度”)

那么很显然这两种构造方式,都是由2个float型参数的,对于构造函数将无能为力,而静态工厂方法可以从方法名来区别开,而且还带来了易于辨识的好处:

public class Complex {  
      
    private final float re;  
    private final float im;  
  
    private Complex(float re, float im){  
        this.re = re;  
        this.im = im;  
    }  
  
    public static Complex valueOf(float re, float im){  
        return new Complex(re, im);  
    }  
  
    public static Complex valueOfPolar(float r, float theta){  
        return new Complex((float)(r * Math.cos(theta)), (float)(r * Math.sin(theta)));  
    }  
}  

注意:用静态工厂方法代替构造函数后,构造函数就成了private的了,当然如果你希望同时也提供公有的构造函数也是可以的。

2)它与构造函数不同,在每次被调用时,不要求非得创建一个新的对象。

静态工厂方法能够为重复的调用返回相同对象,这有助于类总能控制在某个时刻哪些实例应该存在。这种类被称作实例受控的类

3)它与构造函数不同,它们可以返回原返回类型的任何子类型的对象

这样在选择返回类型时更具有灵活性,此外,使用这种静态工厂方法时,甚至要求客户端通过接口来引用被返回的对象,而不是通过它的实现类来引用被返回的对象。(详见64条)

4)静态工厂所返回的对象的类可以随着每次调用而发生变化,这取决于静态工厂方法的参数值。
只要是已声明的返回类型的子类型,都是允许的。返回对象的类也可能随着发行版本的不同而不同。例如EnumSet类没有公有的构造器,只有静态工厂方法。
在这里插入图片描述
该图为 EnumSet方法的部分截图EnumSet方法的部分截图

5)静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在。

使用静态工厂方法的缺点有:
1)静态工厂方法主要缺点在于,类如果不含公有的或者受保护的构造器,就不能被子类化。

2)程序员很难发现他们。
下面是静态工厂方法的一些惯用名称:
在这里插入图片描述
Type 表示工厂方法所返回的对象类型,例如:

BufferedReader br = Files.newBufferedReader(path);
  • Type ----- getType 和 newType 的简版,例如
List<Complaint> litany = Collections.list(legacyLitany);
Reference:
  1. 《Effective Java(第三版)》Chapter 2:创建和销毁对象
  2. TonyLian https://tonylian.iteye.com/blog/378830
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值