Java中用静态工厂方法代替构造器的优缺点
来源:互联网 发布:精通matlab最优化.pdf 编辑:程序博客网 时间:2024/05/24 06:12
Effective Java学习笔记,静态工厂方法的善用。
一般情况下,对于类而言,我们获取一个类的实例时,最常用的方法是提供一个公有的构造器。
但是还有一种方法,类可以提供一个公有的静态工厂方法,它只是个返回类的实例的静态方法而已。但是静态工厂方法却又许多妙用之处。
注意:类的静态工厂方法与设计模式中的工厂方法不同。
Android源码中打量使用了静态工厂方法。例如:
//Watchdog.javapublic static Watchdog getInstance() { if (sWatchdog == null) { sWatchdog = new Watchdog(); } return sWatchdog; }
为什么Android源码中会打量使用静态工厂方法呢?静态工厂方法与构造器相比有哪些优势呢?
1)它们有名称。客户端调用的时候见名知意,而且易于阅读。比如getInstance方法,用户调用的时候见名知意,就知道调用该方法可以获得其所在类的一个实例。当一个类有多个相同签名的构造器的时候,就用静态工厂方法代替构造器,避免了用户不知道该调用哪个构造器的问题。
2)不必每次调用它们的时候都创建一个新对象。尤其是在单实例类中使用非常广泛,比如上面列举的Watchdog.java中的getIns()方法,sWatchdog对象实际上只创建了一次,其他需要用Watchdog类的实例的地方,只需要调用getInstance()方法一次,就可以获取该对象,简单方便。
3)可以返回原返回类型的任何子类型对象。这个主要根据传入工厂静态方法的参数来实现,只要是已声名的返回类型的子类型,都是可以的。这为我们选择返回对象的类型提供了灵活性。
例如Android源码中ArraySet.java中的方法toArray,newInstance中的参数array.getClass().getComponentType() 即确定了new出来的对象是什么类型的。所有的JAVA类都继承自object,那数组也不例外,数组的数据的类型可以是int或者String等,由getComponentType()来决定。这样就体现了上边说的灵活性,返回对象的类型由array决定。
@Override public <T> T[] toArray(T[] array) { if (array.length < mSize) { @SuppressWarnings("unchecked") T[] newArray = (T[]) Array.newInstance(<span style="color:#3333ff;background-color: rgb(255, 255, 255);">array.getClass().getComponentType(), mSize</span>); array = newArray; } System.arraycopy(mArray, 0, array, 0, mSize); if (array.length > mSize) { array[mSize] = null; } return array; }
4)创建参数化类型实例的时候,使得代码更加简洁。
调用参数化构造器的时候,通常要两次提供类型参数:
Map<String, List<String>> m = new HashMap<String, List<String>>();
使用静态工厂方法后,情况就不一样了:
public static <K, V>HashMap<K, V> newInstance( ) {return new HashMap<K, V>();}于是上边创建m实例的的代码,就变成了下面这样:
Map<String, List<String>> m = HashMap.newInstance();是不是感觉简洁了许多呢?newInstance()只需要写一次,其他地方就可以直接调用了。
任何事物都有其两面性,静态工厂方法当然也有其缺点:
1)类如果不含公有的或者受保护的构造器,就不能被子类化。什么意思呢?就是说如果类没有public或者protected修饰的构造器,那么就不能被另外一个类所继承,也就是所谓的子类化。
2)它们与其他的静态公有方法实际上没有任何区别。
在API文档中,它们没有像构造器那样在API文档中被明确标识出来,因此,对于提供了静态工厂方法而不是构造器的类来说,要想查明如何实例化一个类,是非常困难的。
下面是静态工厂方法的一些惯用名称:
- valueOf 该方法返回的实例与参数具有相同的值,实际是类型转换方法。
- of valueOf的一种替代,EnumSet。
- getInstance Singleton单例模式,返回唯一的实例。
- newInstance 返回的实例是一个新的实例,与之前返回的都不相同。
- getType 与getInstance一样,但是在工厂方法处于不同的类时候使用。
- newType 与getInstance一样,但是在工厂方法处于不同的类时候使用。
0 1
- Java中用静态工厂方法代替构造器的优缺点
- 静态工厂方法代替构造函数的优缺点
- [Effective Java]考虑用静态工厂方法代替构造器
- 《Effective Java》-考虑用静态工厂方法代替构造器
- Effective Java -- 用静态工厂方法来代替构造器
- effective java--关于静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- 用静态工厂方法代替构造器
- 静态工厂方法代替构造器
- 考虑使用静态工厂方法代替类的构造器
- 静态工厂方法代替构造器的总结
- 《Effective Java》: 考虑用静态工厂方法代替构造函数
- 考虑使用静态工厂方法代替构造器
- 01、考虑用静态工厂方法代替构造器
- 考虑用静态工厂方法代替构造器
- 【代码优化】考虑使用静态工厂方法代替构造器
- 摄像机按层响应事件Camera.eventMask
- 使用log4j 2
- 前端面试题目(2)
- Android简易实战教程--第二十六话《网络图片查看器在本地缓存》
- 将Excel文件导入数据库(POI+Excel+MySQL)(jsp页面导入)
- Java中用静态工厂方法代替构造器的优缺点
- Bound服务之Binder
- UVa 11759 洛克人的难题 状压dp
- java 读取标准输入
- shell特殊用法
- AES,SHA1,DES,RSA,MD5区别
- POJ_1010_STAMPS
- Shell中的函数调用
- IO学习笔记(一)