关于 Java 的静态工厂方法,看这一篇就够了!

简介: 关于 Java 的静态工厂方法,看这一篇就够了!

1. 序:什么是静态工厂方法


在 Java 中,获得一个类实例最简单的方法就是使用 new 关键字,通过构造函数来实现对象的创建。


就像这样:


    Fragment fragment = new MyFragment();
    // or
    Date date = new Date();


不过在实际的开发中,我们经常还会见到另外一种获取类实例的方法:


 Fragment fragment = MyFragment.newIntance();
    // or 
 Calendar calendar = Calendar.getInstance();
    // or 
 Integer number = Integer.valueOf("3");


↑ 像这样的:不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的静态工厂方法(Static factory method)。


知识点:new 究竟做了什么?


简单来说:当我们使用 new 来构造一个新的类实例时,其实是告诉了 JVM 我需要一个新的实例。JVM 就会自动在内存中开辟一片空间,然后调用构造函数来初始化成员变量,最终把引用返回给调用方。


静态工厂方法的优势

2.1 静态工厂方法与构造器不同的第一优势在于,它们有名字

由于语言的特性,Java 的构造函数都是跟类名一样的。这导致的一个问题是构造函数的名称不够灵活,经常不能准确地描述返回值,在有多个重载的构造函数时尤甚,如果参数类型、数目又比较相似的话,那更是很容易出错。


比如,如下的一段代码 :


Date date0 = new Date();
Date date1 = new Date(0L);
Date date2 = new Date("0");
Date date3 = new Date(1,2,1);
Date date4 = new Date(1,2,1,1,1);
Date date5 = new Date(1,2,1,1,1,1);


—— Date 类有很多重载函数,对于开发者来说,假如不是特别熟悉的话,恐怕是需要犹豫一下,才能找到合适的构造函数的。而对于其他的代码阅读者来说,估计更是需要查看文档,才能明白每个参数的含义了。


(当然,Date 类在目前的 Java 版本中,只保留了一个无参和一个有参的构造函数,其他的都已经标记为 @Deprecated 了)


而如果使用静态工厂方法,就可以给方法起更多有意义的名字,比如前面的 valueOf、newInstance、getInstance 等,对于代码的编写和阅读都能够更清晰。


2.2 第二个优势,不用每次被调用时都创建新对象

这个很容易理解了,有时候外部调用者只需要拿到一个实例,而不关心是否是新的实例;又或者我们想对外提供一个单例时 —— 如果使用工厂方法,就可以很容易的在内部控制,防止创建不必要的对象,减少开销。

静态工厂一般和单例模式联系在一起的。

在实际的场景中,单例的写法也大都是用静态工厂方法来实现的。


2.3 第三个优势,可以返回原返回类型的子类

2.4 第四个优势,在创建带泛型的实例时,能使代码变得简洁

除此之外

3.1 可以有多个参数相同但名称不同的工厂方法

3.2 可以减少对外暴露的属性

3.3 多了一层控制,方便统一修改


3总结

总结

总体来说,我觉得『考虑使用静态工厂方法代替构造器』这点,除了有名字、可以用子类等这些语法层面上的优势之外,更多的是在工程学上的意义,我觉得它实质上的最主要作用是:能够增大类的提供者对自己所提供的类的控制力。


作为一个开发者,当我们作为调用方,使用别人提供的类时,如果要使用 new 关键字来为其创建一个类实例,如果对类不是特别熟悉,那么一定是要特别慎重的 —— new 实在是太好用了,以致于它经常被滥用,随时随地的 new 是有很大风险的,除了可能导致性能、内存方面的问题外,也经常会使得代码结构变得混乱。


而当我们在作为类的提供方时,无法控制调用者的具体行为,但是我们可以尝试使用一些方法来增大自己对类的控制力,减少调用方犯错误的机会,这也是对代码更负责的具体体现。


目录
相关文章
|
设计模式 Java 开发者
Java中23种设计模式之静态工厂方法
Java中23种设计模式之静态工厂方法
189 0
Effective Java--第1条静态工厂方法代替构造方法
Effective Java--第1条静态工厂方法代替构造方法
120 0
Effective Java--第1条静态工厂方法代替构造方法
|
缓存 架构师 Java
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(下)
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(下)
201 0
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(下)
|
设计模式 架构师 Java
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(中)
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(中)
90 0
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(中)
|
设计模式 架构师 Java
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(上)
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(上)
71 0
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器(上)
|
9天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
9天前
|
安全 Java 开发者
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第9天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细解析Java中的同步机制,包括synchronized关键字、Lock接口以及并发集合等,并探讨它们如何影响程序的性能。此外,我们还将讨论Java内存模型,以及它如何影响并发程序的行为。最后,我们将提供一些实用的并发编程技巧和最佳实践,帮助开发者编写出既线程安全又高效的Java程序。
22 3
|
11天前
|
Java
Java 并发编程:深入理解线程池
【4月更文挑战第8天】本文将深入探讨 Java 中的线程池技术,包括其工作原理、优势以及如何使用。线程池是 Java 并发编程的重要工具,它可以有效地管理和控制线程的执行,提高系统性能。通过本文的学习,读者将对线程池有更深入的理解,并能在实际开发中灵活运用。
|
9天前
|
算法 Java 开发者
Java中的多线程编程:概念、实现与性能优化
【4月更文挑战第9天】在Java编程中,多线程是一种强大的工具,它允许开发者创建并发执行的程序,提高系统的响应性和吞吐量。本文将深入探讨Java多线程的核心概念,包括线程的生命周期、线程同步机制以及线程池的使用。接着,我们将展示如何通过继承Thread类和实现Runnable接口来创建线程,并讨论各自的优缺点。此外,文章还将介绍高级主题,如死锁的预防、避免和检测,以及如何使用并发集合和原子变量来提高多线程程序的性能和安全性。最后,我们将提供一些实用的性能优化技巧,帮助开发者编写出更高效、更稳定的多线程应用程序。