创建和销毁对象——用静态工厂方法代替构造器
Posted lbhym
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建和销毁对象——用静态工厂方法代替构造器相关的知识,希望对你有一定的参考价值。
参考资料:《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();//输出这是大号 } }
静态工厂方法不止这几点,其他的一些优势我可能还没发现,剩下知道的几个以目前的能力来看,还无法完全理解。
以上是关于创建和销毁对象——用静态工厂方法代替构造器的主要内容,如果未能解决你的问题,请参考以下文章