Effective Java--创建和销毁对象--1~5条

  • 静态工厂方法

解释:类中定义共有的静态方法返回类的实例(可以是该类本身,也可以是别的类)。

优势:

  1. 静态工厂方法可以有名称
  2. 静态工厂方法与构造器不同的优势,不必在每次调用它们的时候都创建一个新对象
  3. 静态工厂方法可以返回原返回类型的任何子类型
  4. 静态工厂方法所返回的对象的类,可以随着每次调用发生变化
  5. 方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在 

其中第2~5点有些啰嗦,牵强附会。构造器的本意就是构造类的实例,因此,构造器的返回类型就被限定了,也不能算什么缺憾。而静态工厂方法其实就是普通的静态方法,当然可以返回任意类型。不过相对于构造器生成实例,静态工厂方法提到的第一点优势--可以有名称实在比较好用。

对于下面这个类,如果再想写入参为一个int型的初始化bb构造函数是不可以的了,因为函数类型时根据入参类型,而不是入参名区分的。

public Class A{
    int aa = 0;
    int bb = 0;
    public A(int tmp){
        aa = tmp;
        bb = 0;
    }
}

因此可以使用静态工厂方法,直接通过不同的函数命令来实例化类,如下:

public Class A{
    int aa = 0;
    int bb = 0;
    private static final DEAINSTANCE = new A(0,0);
    private A(int aa, int bb){
        aa = aa;
        bb = bb;
    }

    //该静态方法可以用来修改aa的值
    public static A newAwithaa(int aa){
        retuan new A(aa, 0);
    }

    //该静态方法可以用来修改bb的值
    public static A newAwithbb(int bb){
        retuan new A(0, bb);
    }

    //该静态方法获取一个默认的实例,而不重新构造新的对象
    public static A getInstance(){
        return DEAINSTANCE;
    }

}

下面列出静态工厂方法的惯用名称:

from--类型转换方法,从A实例转成B实例

of-----聚合方法 ,聚合多个参数,生成新的实例

valueOf---比from和of更烦琐的替代方法

instance/getInstance----根据入参(如果有)返回不同的实例

create/newInstance-----根据入参(如果有)返回不同新的实例

getType----类似getInstance

newType---类似newInstance


  • 构建器

背景:遇到多个构造器参数时,一般的重叠构造器模式会导致混乱。构造器函数名称相同,仅入参不同,如果有5个参数,那么该模式的构造器将至少有五个,使用时很混乱,不方便。使用javaBeans模式虽然可以一定程度解决这种混乱问题,但是割裂了实例的初始化过程,可能在第一次和第二次使用同一个实例之间,调用了set某个参数的方法,导致实例实际上不同;并且JavaBeans模式使得把类做成不可变的可能性不复存在。

解释:构建器不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法生成通常是不可变的对象。

以下代码是一个builder模式的示例:

Builder是待构建的类的一个内部类,Builder类具有该类的所有属性每个属性都提供了一个方法进行设置,并且设置方法的返回类型为Builder。这一特点使得可以链式调用各个设置函数。在链式的末端,使用一个无参的build函数构建该类,build函数返回一个类的构造函数,构造函数的入参为Builder的一个实例

public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;

    public static class Builder {
        private final int servingSize;
        private final int servings;
        private int calories = 0;

        public Builder(int servingSize, int servings){
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val){
            this.calories = val;
            return this;
        }

        public  NutritionFacts build(){
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder){
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
    }

    public static void main(String[] args) {
        NutritionFacts cocaCola = new Builder(5, 20).calories(5).build();
    }
}

 


  • 私有构造器

  • 优先考虑依赖注入

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值