好处

  1. 有名称,能见名知意。例如BigInteger的probablePrime方法

  2. 享元模式、单例模式中使用

享元模式:创建对象代价很高,重复调用已有对象,例如数据库连接等。享元模式是单例模式的一个拓展。

  1. 可以返回原类型的任何子类型

  2. 可以通过参数值添加业务逻辑返回不同对象,基于第3点

interface Demo {
    static Demo getDemoByParam(Integer param) {
        if (param > 0) {
            return new BigDemo();
        } else {
            return new SmallDemo();
        }
    }
}
private static class BigDemo implements Demo {
}
private static class SmallDemo implements Demo {
}
  1. 可以返回不存在的类的对象,服务提供者框架例如JDBC,java1.6java提供一个服务提供者框架 java.util.ServiceLoader(JDBC早于ServiceLoader所以没有使用它)

服务提供者框架包括:

  1. 服务者接口,提供服务的接口如JDBC的Connection接口

  2. 服务提供者接口,获取服务提供者的接口如JDBC的Driver接口,如下是mysql提供的实

 public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
            //我们在使用的时候 Class.forName("com.mysql.jdbc.Driver")会加载该启动,并调用服务提供者注册API进行注册驱动
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
    public Driver() throws SQLException {
    }
}
  1. 服务提供者注册API(DriverManager.registerDriver())

  //mysql生产厂方提供并使用它在我们加载其Driver的时候进行注册
  1. 服务访问API(DriverManager.getConnection())

  //我们可以直接,加载Driver后我们可以通过它获取服务对象Connection
 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/education5?serverTimezone=Asia/Shanghai","root","123456");

java.util.ServiceLoader方式:

//服务接口
public class Hello{
 void hello();
}

public class DemoUtils {
 //服务注册API和访问API,这里因为是demo所以卸载了一起
public static void hello(){
    ServiceLoader<Hello> load = ServiceLoader.load(Hello.class);
    for (Hello hello : load) {
        hello.hello();
    }
}
}
//服务接口实现
public class HelloImpl1 implements Hello {
@Override
public void hello() {
    System.out.println("HelloImpl1.hello");
}

public static void main(String[] args) {     //测试代码
    DemoUtils.hello();
}
}

在classpath下创建对应接口目录的文件/META-INF/services/com.demo.Hello文件注册我们写的实现类即可

com.demo.Hello文件

com.demo.HelloImpl1

缺点

  1. 不包含共有或者受保护的构造器,导致无法被继承。这样也因祸得福,鼓励程序员使用组合而不是继承。

  2. 静态工厂方法一般和类或者接口分离出来,例如Collection和Collections。如果静态工厂方法所在的类没有提供API我们就很难找到类的实例化方法了。通过类或者接口注释并遵守命名规范来弥补这一劣势如下部分,实际使用过程中可以查询或者百度

  • from——类型转换方法,单个参数,返回一个像相对应的实例

  • of——聚合方法,带有多个参数,多个实例聚合成一个实例

  • instance或者newInstance 通过方法参数创建实例(也可以没有参数)

  • create或者newInstance 通过参数方法创建实例但是每次创建一个新的实例

effective解读-第一条 静态工厂创建对象代替构造器的更多相关文章

  1. EFFECTIVE JAVA 第一天 静态工厂方法

    静态工厂方法:(这里指的是就是普通static方法),类可以通过静态工厂方法提供给它的客户端,而不是通过构造器.提供静态工厂方法而不是公有构造器,这样做有几大优势. 在类的实现中使用了API的类被称为 ...

  2. Java - 用静态工厂方法代替构造器

    Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...

  3. Effective java读书札记第一条之 考虑用静态工厂方法取代构造器

    对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...

  4. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  5. effective java 3th item1:考虑静态工厂方法代替构造器

    传统的方式获取一个类的实例,是通过提供一个 public 构造器.这里有技巧,每一个程序员应该记住.一个类可以对外提供一个 public 的 静态工厂方法 ,该方法只是一个朴素的静态方法,不需要有太多 ...

  6. 【Effective Java读书笔记】创建和销毁对象(一):考虑使用静态工厂方法代替构造器

    类可以提供一个静态方法,返回类的一个静态实例,如Boolean包装类的一个获取实例的静态方法 public static Boolean valueOf(boolean b) { return (b ...

  7. 【读书笔记 - Effective Java】01. 考虑用静态工厂方法代替构造器

    获取类的实例有两种方法: 1. 提供一个公有的构造器(最常用). 2. 提供一个公有的静态工厂方法(static factory method). // 静态工厂方法示例 public static ...

  8. 高效JAVA之用静态工厂方法代替构造器

    程序员这行干的久了,总会染上一些恶习,我就染上一个让人深恶痛绝,自己却津津乐道的习惯,还不想改的那种,它可以叫做强迫症,也可以叫做洁癖.那就是我不允许我的IDEA出现一点点警告,什么黄色背景,绿色波浪 ...

  9. 静态工厂方法VS构造器

    我之前已经介绍过关于构建者模式(Builder Pattern)的一些内容,它是一种很有用的模式用于实例化包含几个属性(可选的)的类,带来的好处是更容易读.写及维护客户端代码.今天,我将继续介绍对象创 ...

随机推荐

  1. Web 前端 UI 组件库文档自动化方案 All In One

    Web 前端 UI 组件库文档自动化方案 All In One 需求 自动化 动态 好用 markdown element-ui 中示例和说明按照一定规则写在md文件中,调用md-loader将md文 ...

  2. how to measure function performance in javascript

    how to measure function performance in javascript Performance API Performance Timeline API Navigatio ...

  3. website & blogs & about me & contact

    website & blogs & about me & contact demos https://davidwalsh.name/about-david-walsh htt ...

  4. 《容器高手实战: Dockerfile最佳实践》

    Dockerfile最佳实践一个容器对应一个进程一个Docker容器应该只对应一个进程,也就是一个Docker 镜像一般只包含一个应用的制品包(比如.jar). 在需要组合多个进程的场景,使用容器组( ...

  5. Python学习笔记_购物车案例

    goods_dic = { "iphone":6000, "ipad":3000, "T-shirt":100, "coffee& ...

  6. C# NOPI 项目实战(经典)(可下载项目源码)

    1 -.首先说明下项目目的: 之前我有写过一篇  "NPOI操作EXCEL" 这篇文章主要介绍了如何安装NPOI,以及NPOI具体如何使用,并且用具体实例介绍了excel导入到da ...

  7. Elasticsearch---DSL搜索实践

    Domain Specific Language 特定领域语言,基于JSON格式的数据查询,查询更灵活,有利于复杂查询 一.普通url路径参数搜索 数据准备 1.建立名字为 shop 的索引 2.手动 ...

  8. AI数学基础之:奇异值和奇异值分解

    目录 简介 相似矩阵 对角矩阵 可对角化矩阵 特征值 特征分解 特征值的几何意义 奇异值 Singular value 奇异值分解SVD 简介 奇异值是矩阵中的一个非常重要的概念,一般是通过奇异值分解 ...

  9. 谈一下HashMap的底层原理是什么?

    底层原理:Map + 无序 + 键唯一 + 哈希表 (数组+Entry)+ 存取值 1.HashMap是Map接口的实现类.实现HashMap对数据的操作,允许有一个null键,多个null值. Co ...

  10. Svelte 极简入门

    ​弹指之间即可完成.   注意:原文发表于 2017-8-7,随着框架不断演进,部分内容可能已不适用.     Svelte 是一种新型框架.   以往我们要引入一个框架或者类库,可以通过在页面上放置 ...