创建和销毁对象——用静态工厂方法代替构造器

参考资料:《Effective Java》,https://www.jianshu.com/p/ceb5ec8f1174

基础回顾

1.什么是构造器?

构造器与类同名,在新建一个类的对象时,构造器会运行,以便将实例初始化为所希望的状态。

每个类都会有一个默认的无参的构造器。也可以自己手动写一个构造器。

如,在People类中写一个构造器:

public People(String Name,int Age)
{
    this.Name=Name;
    this.Age=Age;
}

然后新建一个关于这个类的实例

People a=new Prople("张三",18);

像上面这样,可以在new后面加入对应的参数。如果我们不加参数,就会调用默认的无参构造器。

2.工厂方法

这里的静态工厂方法并不是直接对应设计模式当中的工厂方法

静态工厂方法常用于类似LoaclDate或NumberFormat这种类当中。比如LocalDate.now等。

为什么会用静态工厂方法呢?比如NumberFormat.getCurrencyInstance()和NumberFormat.getPercentInstance()这两个工厂方法,一个得到的是货币类型的,一个是百分比类型的。

但是他们的接收参数都是一样的,构造器又必须得和类同名,如果非得用构造器去实现这个功能,还得添加其他参数,同时没有明确的名字去区分,增加了开发者的使用难度。

下面将会详细说出静态工厂方法的其他优势。

静态工厂方法的优势

先自己写个静态工厂方法

public class EJ01_01 {
    private int Num = 0;

    //静态工厂方法
    public static EJ01_01 convert(double Num) {
        EJ01_01 ej01_01 = new EJ01_01();
        ej01_01.Num = (int) Num;
        return ej01_01;
    }
    //测试可以返回子类
    public static EJ01_01_Son convert() {
        return new EJ01_01_Son();
    }

    public int Show() {
        return this.Num;
    }

    public int Add_10() {
        return this.Num + 10;
    }
}

class Test {
    public static void main(String args[]) {
        EJ01_01 test = EJ01_01.convert(1.2);
        System.out.println(test.Add_10());//输出11
        System.out.println(test.Show());//输出1
    }
}
//子类
class EJ01_01_Son extends EJ01_01 {
}

1.静态工厂方法有名称。

这个不用多说,就像上面的NumberFormat.getCurrencyInstance()和NumberFormat.getPercentInstance()一样。开发者一眼就可以看出他们的区别。

2.不必在每次调用时都创建一个新的对象。

如上面的代码。在测试类中:

EJ01_01 test = EJ01_01.convert(1.2);

并没有新建任何对象,直接调用。

3.它可以返回原返回类型的任何子类

构造函数只能返回自己原本的类型,但是在静态工厂方法中是可以返回子类的。如:

 //测试可以返回子类
    public static EJ01_01_Son convert() {
        return new EJ01_01_Son();
    }

我测试了也可以返回其他常见的数据类型,比如convert方法的返回类型可以直接写成int,但是不见资料当中有任何提及,也不知道这种写法是否规范。

4.可以减少对外暴露的属性

下面代码的功能,调用Get_Type时,只能输入规定的参数,然后输出对应的数据。

这种情况非常常见,比如一些方法只让输入MAX、MIN这种参数,输入其他参数直接报错。

但是我们如果只用构造器来实现,是限制不了用户输入的是什么。下面的代码相当于把静态工厂方法当成构造函数的参数,用户只能调用对应的静态工厂方法,然后工厂方法进行赋值。

class Get_Type {
    public static final int TYPE_Small = 1;
    public static final int TYPE_Moderate = 2;
    public static final int TYPE_Big = 3;

    private Get_Type(int type) {
        switch (type){
            case 1:
                System.out.println("这是小号");
                break;
            case 2:
                System.out.println("这是中号");
                break;
            case 3:
                System.out.println("这是大号");
                break;
        }
    }

    public static Get_Type Small() {
        return new Get_Type(TYPE_Small);
    }
    public static Get_Type Moderate() {
        return new Get_Type(TYPE_Moderate);
    }
    public static Get_Type Big() {
        return new Get_Type(TYPE_Big);
    }
}

//调用
class Test2{
    public static void main(String args[]){
        Get_Type get_small=Get_Type.Big();//输出这是大号
    }
}

静态工厂方法不止这几点,其他的一些优势我可能还没发现,剩下知道的几个以目前的能力来看,还无法完全理解。

原文地址:https://www.cnblogs.com/lbhym/p/11787505.html

时间: 2024-08-02 21:51:17

创建和销毁对象——用静态工厂方法代替构造器的相关文章

第二章、创建和销毁对象。ITEM1:考虑用静态工厂方法代替构造器

除了使用构造器来获取类的一个实例,还可以使用静态工厂方法(static factory method). 下面的方法是将boolean基本类型转成一个Boolean对象引用: 1 public final class Boolean implements java.io.Serializable, 2 Comparable<Boolean> 3 { 4 //与基本类型boolean=true匹配 5 public static final Boolean TRUE = new Boolean(

Effective JAVA NO1考虑用静态工厂方法代替构造器

NO1.考虑用静态工厂方法代替构造器 静态工厂方法与构造器不同的第一大优势在于它们有名称: 静态工厂方法与构造器不同的第二大优势在于,不必在每次调用它们的时候都创建一个新对象: 第三大优势,它们可以返回原返回类型的任何子类型的对象: 第四大优势,在创建参数化类型实例的时候,它们使代码变得更加简洁: 缺点: 1.类如果含公有的或者受保护的构造器,就不能被子类化. 2.它们与其他的静态方法实际不上没有任何区别.

[Effective Java]考虑用静态工厂方法代替构造器

本文主要介绍如何使用静态工厂方法已经在那种场合来使用这种方式代替构造方法. 众所周知,对于类而言,我们为了获得一个类的实例对象,通常情况下会提供一个公有的(public) 的构造器.当然除了这种方法以外,我们还可以通过给类提供一个public的静态工厂方法(static factory method)的方式来完成,让它返回一个类的实例. 先看一个简单的Boolean的示例,这个示例将boolean基本类型值转换成一个Boolean对象的引用. public static Boolean valu

Effective java读书札记第一条之 考虑用静态工厂方法代替构造器

对于类而言,为了让客户端获取它资深的一个实例,最常用的方法就是提供一个共有的构造器.还有一种放你发,也应该子每个程序员的工具箱中占有一席之地.类可以提供一个共有的静态 工厂方法,它只是返回类的实例的静态方法. 类可以通过静态工厂方法类提供它的客户端(对象),而不是通过构造器.提这样做的好处有: 1.静态工厂方法与构造器不同的第一大优势在于,它们有名称.比如构造器BigInteger(int,int,Random)返回的BigInteger可能为素数,如果用名为BigInteger.probabl

【代码优化】考虑使用静态工厂方法取代构造器

静态工厂方法与设计模式中的工厂方法模式不同,和设计模式中的工厂方法模式不直接相应. 使用静态工厂方法比构造器的优势: 第一.静态工厂方法是有名称的,而构造器是通过參数推断的. 每一个静态工厂方法都有自己的名字,能够依据名称就能够推断它要做什么事情,而构造器是做不到的. 如:构造器BigInteger(int,int),返回BigInteger能够是素数,偶数等.而用名称BigInteger.probalePrime的静态工厂方法 就一目了然了,代码easy阅读. 第二.不必再每次调用时候都创建一

Efflective Java读书笔记 第一条 考虑用静态工厂方法代替构造器

创建一个类的实例的方法,最常用的是提供一个公有[public]的构造器,另外还有一种方法是类可以提供一个公有的静态工厂方法. 静态工厂方法对于构造器有着不同的优势和劣势. 优势: 1.静态工厂方法可定义更有意思的名称,而构造函数只能是类名. eg:BigInteger的构造函数返回的可能是素数,不过使用BigInteger.probablePrime更加明确. 2.静态工厂方法不必没有调用的时候都创建一个新的对象,这对于不可变类可以预先构造好实例,调用时静态工厂方法直接返回即可. eg:Bool

Effective Java 读书笔记(一):使用静态工厂方法代替构造器

这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文<java中final与static的使用场景总结>. 什么是静态工厂方法? 可以参考书中的例子(摘自JDK1.7 java.lang.Boolean) public final class Boolean implements java.io.Serializable, Comparable<

改善JAVA代码01:考虑静态工厂方法代替构造器

前言 系列文章:[传送门]   每次开始新的一本书,我都会很开心.新书新心情. 正文 静态工厂方法代替构造器 说起这个,好多可以念叨的.做了一年多的项目,慢慢也有感触. 说起构造器 大家很明白,构造器可以让我们在何处何地获取自身或者他人一个实例.我们是无忌惮的使用着 new 却从来没考虑过人家的感受.其实new ,new一个对象,就是开辟一块内存空间给这个对象.如果何处何地,都new的话,漫山遍野... 五颜六色的new ,本质却一样 一句话:构造器虽是万能,但是要珍惜. 再谈谈 静态工厂方法

静态工厂方法VS构造器

我之前已经介绍过关于构建者模式(Builder Pattern)的一些内容,它是一种很有用的模式用于实例化包含几个属性(可选的)的类,带来的好处是更容易读.写及维护客户端代码.今天,我将继续介绍对象创建技术. 在我看来,下面这个类是非常有用的例子.有一个RandomIntGenerator 类,产生随机的int类型的整数.如下所示: public class RandomIntGenerator { private final int min; private final int max; pu