比较 Java 静态工厂方法与构造函数
1 什么是静态工厂方法
Java 静态工厂方法是在方法前加上 public static,让这个方法变为公开、静态的方法。该方法返回该类的一个实例,就好像一个工厂生产出一个产品。所以称之为静态工厂方法。在 Boolean.java 中有一个静态工厂方法示例:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
这里返回了一个 Boolean 实例。
2 比较静态工厂方法与构造函数
2.1 名称
静态工厂方法可以根据返回实例的性质,定义出具有自描述性质的方法名称。比如 BigInteger 类定义了一个静态工厂方法 probablePrime,用于返回一个 BigInteger 类型的素数:
public static BigInteger probablePrime(int bitLength, Random rnd) {
if (bitLength < 2)
throw new ArithmeticException("bitLength < 2");
return (bitLength < SMALL_PRIME_THRESHOLD ?
smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
}
但如果是构造函数,那么只能是类名,比如上例中的 BigInteger。这样就无法从名称上判断返回的 BigInteger 实例到底有什么性质。
2.2 缓存
每次调用构造函数都会创建新的对象。如果需要事先创建好对象,并缓存起来,以供后期复用。那么构造函数方式就不能满足该需求。而静态工厂方法就可以实现。比如 Boolean.java 中的 valueOf 方法,实际上返回的是实现创建好的静态属性 TRUE 与 FALSE:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
下面是事先静态初始化好的TRUE 与 FALSE:
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code true}.
*/
public static final Boolean TRUE = new Boolean(true);
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code false}.
*/
public static final Boolean FALSE = new Boolean(false);
2.3 子类
拥有构造函数的类,可以被子类所继承。但只有静态工厂方法的类却不行。可以使用类组合方式来解决这一问题。
2.4 总结
比较 | 静态工厂方法 | 构造函数 |
---|---|---|
名称 | 可根据情况自定义名称 | 只能是类名 |
缓存 | 可调用重复对象 | 每次调用都创建新的对象 |
子类 | 不能被子类继承 | 可以被子类继承 |
3 静态工厂方法命名方式
关键词 | 说明 | 入参个数 | 示例 |
---|---|---|---|
from | 类型转换,A 类型转换为 B 类型。 | 1 | public static Date from(Instant instant) |
of | 聚合,做合并。 | n | public static <E extends Enum> EnumSet of(E e1, E e2, E e3) |
instance | 返回实例,可能是新建的,也可能是复用已创建的实例。 | n | public static Object instance(int length) |
create | 返回新建的实例。 | n | public static Object create(int length) |
type | 工厂方法不在要返回的类实例中,type 是要返回的类名称。 | n | public static ArrayList list(Enumeration e) |
最后一个示例,方法定义在 Collections 中,要返回的是 ArrayList 实例,所以被命名为 list。
public static <T> ArrayList<T> list(Enumeration<T> e) {
ArrayList<T> l = new ArrayList<>();
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
建议优先考虑使用静态工厂方法来实例化类。
JoshuaBloch. Effective Java中文版.3版[M]. 机械工业出版社, 2018.p.4-8.
比较 Java 静态工厂方法与构造函数的更多相关文章
- C#的静态工厂方法与构造函数对比
最近,在与同事进行协同编程时,我们开始讨论在C#中初始化新对象的最佳方法.我一直是使用构造函数实现,尽管他倾向于静态工程方法.这引起了关于每种类型的利弊的大量来来回回的讨论. 为了说明我所说的内容,这 ...
- ej3-1优先使用静态工厂方法而非构造函数来创建对象
背景 很早之前就已经自己翻译了,先简单的贴出来,并做一下回顾. 条款1 优先使用静态工厂方法而非构造函数来创建对象 允许客户端创建一个实例的传统方法是:提供一个公共构造函数:有另外一个必须成为每个程序 ...
- java的设计模式 - 静态工厂方法
静态工厂方法,也不知道为何叫这个名字.其实也就是一个静态函数,可以替代构造函数用.大名鼎鼎的 guava 就大量使用这种模式,这是非常有用的模式. 比如是 Integer i = Integer.va ...
- Java 的静态工厂方法
本文转载自:https://www.jianshu.com/p/ceb5ec8f1174 序:什么是静态工厂方法 Effective Java 2.1 静态工厂方法与构造器不同的第一优势在于,它们有名 ...
- Effective Java 读书笔记(一):使用静态工厂方法代替构造器
这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...
- [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Effective Java 第三版——1. 考虑使用静态工厂方法替代构造方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 改善JAVA代码01:考虑静态工厂方法代替构造器
前言 系列文章:[传送门] 每次开始新的一本书,我都会很开心.新书新心情. 正文 静态工厂方法代替构造器 说起这个,好多可以念叨的.做了一年多的项目,慢慢也有感触. 说起构造器 大家很明白,构造器 ...
- Java - 用静态工厂方法代替构造器
Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...
随机推荐
- JVM收藏的文章
JAVA 内存泄露详解(原因.例子及解决) https://blog.csdn.net/anxpp/article/details/51325838 JVM内存区域划分Eden Space.Survi ...
- iOS证书(.p12)和描述文件(.mobileprovision)生成制作教程 By h.l
iOS证书(.p12)和描述文件(.mobileprovision)制作 证书类型分为2种,开发证书和发布证书 1.开发证书(iOS Certificates (Development))(用于真机调 ...
- C# 字符串计算MD5
public static string ComputeMD5 (string text) // 计算字符串的 MD5 { System.Security.Cryptography.MD5Crypto ...
- MySQL架构原理之存储引擎InnoDB数据文件
MySQL架构原理之体系架构 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中简单介绍了MySQL的系统文件层,其中包含了数据文件.那么InnoDB的数据文件是如何分类并存储的呢? 一. ...
- 北大博士生提出CAE,下游任务泛化能力优于何恺明MAE
大家好,我是对白. 何恺明时隔两年发一作论文,提出了一种视觉自监督学习新范式-- 用掩蔽自编码器MAE,为视觉大模型开路. 这一次,北大博士生提出一个新方法CAE,在其下游任务中展现的泛化能力超过了M ...
- schtasks
schtasks create 创建新的计划任务. 语法 schtasks /create /tn TaskName /tr TaskRun /sc schedule [/mo modifier ...
- RFC3918组转发矩阵测试——网络测试仪实操
一.简介 1.RFC3918简介 历史 · 在1999年3月成为正式标准 功能 · 评测网络互连设备或网络系统的性能 · 网络设备: 交换机,路由器- 内容 · 定义了一整套测试方法,为不同厂家的设备 ...
- 深度剖析数仓CN增量备份技术
摘要:为了解决Roach的性能问题,提出了CN增量备份手段,从而达到进一步优化RPO目的. 本文分享自华为云社区<GaussDB(DWS)备份容灾之CN增量备份>,作者: zxy_db . ...
- Oracle之SQL限定查询
WHERE限定条件 /*语法结构:SELECT * | 列名1[,列名2...] | 表达式FROM 表名 WHERE 限定条件; */ --查询职位为CLERK的员工信息 SELECT * FROM ...
- Nginx平滑升级的详细操作方法
转至:https://blog.csdn.net/midion9/article/details/49684325 一.平滑升级概述Nginx方便地帮助我们实现了平滑升级.其原理简单概括,就是:(1) ...