JAVA 静态工厂方法
来源:互联网 发布:linux 修改文件时间戳 编辑:程序博客网 时间:2024/05/22 01:46
静态工厂方法是一个类产生一个该类实例的静态方法,用于补充或取代类的构造器。
例如 Boolean 中有如下代码段,其中 valueOf 就是一个静态工厂方法。
//...public static final Boolean TRUE = new Boolean(true);public static final Boolean FALSE = new Boolean(false);//... public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE);}
注意,工厂模式中也有工厂方法,这和这里的静态工厂方法是不一样的。
使用静态工厂方法提供类的实例有以下一些优点。
1)静态工厂方法可以有不同于类名的名字,用户更容易从方法名猜测到其用途,例如 BigInteger 类中有一个静态工厂方法
public static BigInteger probablePrime(int bitLength, Random rnd){ //...}
该方法为用户返回一个很可能是质数的大整数。
2) 如上述 Boolean 类的方法 valueOf 所表现的, 静态工厂方法不需要新生成一个类的实例,它只是返回一个类的实例,这种方式常常能够提供效率上的改善。静态工厂方法常应用于单例模式中(Effective Java 中推荐使用枚举类型实现单例),保证一个类只被实例化一次,其它地方需要该类的实例是,总是返回同一个实例。
public class Singleton { // 饿汉模式,JVM 只产生一个静态变量实例,避免线程安全问题,但增大了系统开销 private static final Singleton INSTANCE = new Singleton(); private Singleton() { //do something here } public static Singleton getInstance(){ return INSTANCE; }}
另外,在实现不可变类(immutable class)时,也常常用静态工厂方法提供类的实例。
3) 静态工厂方法可以返回当前类的子类实例,从而在不暴露子类的前提下,使用子类的实例,这也是构造方法不具备的功能。
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> implements Cloneable, java.io.Serializable{ //... public <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType){ Enum<?>[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); if (universe.length <= 64) return new RegularEnumSet<>(elementType, universe); else return new JumboEnumSet<>(elementType, universe); }}
抽象类 EnumSet 的一个静态工厂方法,根据枚举类型的大小,返回不同的 EnumSet 的子类实例。
这样做的另一个好处是解耦合,进而实现功能的易于扩展。例如如果将来有一种效率更好的 EnumSet 的子类时,则只需根据条件返回新的子类实例即可,而已使用该方法的代码并不产生做修改。
JDBC 作为一个 Service Provider 框架,也使用了静态工厂方法。 Service Provider 框架有三个必须的组成部分。
- Service interface 将服务通过抽象统一声明,供客户端调用。由各个服务提供者(Provider)具体实现
- Provider registration API 用于注册已实现了 Service interface 的 Provider,使得客户端可以访问它实现的服务
- Service access API 常常通过一个静态工厂方法,让用户可以获得一个 Provider 的实例进行具体的使用。
结合 JDBC 框架
java.sql.Connection
是服务接口(Service interface),它定义了一系列的标准的服务内容,例如prepareStatement(),commit()
和rollback()
等,但却没有实现这些服务。服务提供者 Provider (Mysql,Oracle 等等)可以根据自己的特点实现这些服务内容,只要 Provider 相应的实现类 (例如oracle.jdbc.driver.PhysicalConnection
类,但我们并不关心这个具体实现类是什么) implements 了 JDBC 的标准接口java.sql.Connection
既能保证其可用性。java.sql.DriverManager.getConnection()
就是 Service access API 的静态工厂方法,它根据参数返回对应的 Connection,参数会指明需要返回的 Connection 的实现类。java.sql.Driver
对应 Service provider interface,Provider 提供该接口的实现类后,在实现类中有一段静态代码,调用java.sql.DriverManager.registerDriver()
方法将其自身注册到系统中,供用户使用。
static { try { if(defaultDriver == null){ defaultDriver = new OracleDriver(); java.sql.DriverManager.registerDriver(defaultDriver); } } catch (RuntimeException localRuntimeException) { } catch (SQLException localSQLException) { }}
这段静态代码将在 JVM 加载该类时自动执行,这也是在建立数据库连接前,要显式调用 Class.forName(“oracle.jdbc.driver.OracleDriver”);
加载 Driver 类的原因。
从以上的描述可以看出,静态工厂方法的作用主要是产生一个自身或者子类的实例,从而完善自身的功能和描述。
而工厂模式则是为了解耦,客户端在需要使用产品类的实例的时候,不需要通过 new 或者产品类的静态工厂方法来产生其实例,而是首先创建工厂类,然后通过工厂类提供的方法来得到产品类的实例。关于工厂模式的研究,将在下一篇博文中给出详细的介绍。
- Java 静态工厂方法
- Java 静态工厂方法
- java 静态工厂方法
- JAVA 静态工厂方法
- Java 基础 静态工厂方法
- Effective Java --静态工厂方法
- Effective Java: 使用静态工厂方法
- java系列_静态工厂方法
- java中简单工厂模式(静态工厂方法模式)
- 静态工厂 工厂方法 抽象工厂
- 静态工厂方法
- 静态工厂方法模式
- 静态工厂方法
- 静态工厂方法
- 静态工厂方法
- 静态工厂方法
- 静态工厂方法
- 静态工厂方法
- 设计模式--策略模式
- .net MVC框架下利用css+js实现遮罩效果
- my presentation2
- OpenGL 的空间变换(上):矩阵在空间几何中的应用
- Python并发之多线程
- JAVA 静态工厂方法
- Android签名机制之---签名过程详解
- jQuery实现点击其他地方div隐藏
- 奇数最大子段和 dp
- 挖地雷问题 dfs
- 如何「优雅」地标数据
- Mask R-CNN
- mysql unoin排序
- 2017.4.20登录页面